linux-user: fix QEMU_STRACE=1 segfault
While debugging some issues with QEMU_STRACE I stumbled over segmentation faults that were pretty reproducible. Turns out we tried to treat a normal return value as errno, resulting in an access over array boundaries for the resolution. Fix this by allowing failure to resolve invalid errnos into strings. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
This commit is contained in:
parent
583359a689
commit
962b289ef3
@ -284,8 +284,13 @@ print_ipc(const struct syscallname *name,
|
|||||||
static void
|
static void
|
||||||
print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
|
print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
|
||||||
{
|
{
|
||||||
if( ret == -1 ) {
|
char *errstr = NULL;
|
||||||
gemu_log(" = -1 errno=%d (%s)\n", errno, target_strerror(errno));
|
|
||||||
|
if (ret == -1) {
|
||||||
|
errstr = target_strerror(errno);
|
||||||
|
}
|
||||||
|
if ((ret == -1) && errstr) {
|
||||||
|
gemu_log(" = -1 errno=%d (%s)\n", errno, errstr);
|
||||||
} else {
|
} else {
|
||||||
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
|
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
|
||||||
}
|
}
|
||||||
@ -1515,14 +1520,19 @@ void
|
|||||||
print_syscall_ret(int num, abi_long ret)
|
print_syscall_ret(int num, abi_long ret)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
char *errstr = NULL;
|
||||||
|
|
||||||
for(i=0;i<nsyscalls;i++)
|
for(i=0;i<nsyscalls;i++)
|
||||||
if( scnames[i].nr == num ) {
|
if( scnames[i].nr == num ) {
|
||||||
if( scnames[i].result != NULL ) {
|
if( scnames[i].result != NULL ) {
|
||||||
scnames[i].result(&scnames[i],ret);
|
scnames[i].result(&scnames[i],ret);
|
||||||
} else {
|
} else {
|
||||||
if( ret < 0 ) {
|
if (ret < 0) {
|
||||||
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret, target_strerror(-ret));
|
errstr = target_strerror(-ret);
|
||||||
|
}
|
||||||
|
if (errstr) {
|
||||||
|
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n",
|
||||||
|
-ret, errstr);
|
||||||
} else {
|
} else {
|
||||||
gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
|
gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
|
||||||
}
|
}
|
||||||
|
@ -731,6 +731,9 @@ static inline int is_error(abi_long ret)
|
|||||||
|
|
||||||
char *target_strerror(int err)
|
char *target_strerror(int err)
|
||||||
{
|
{
|
||||||
|
if ((err >= ERRNO_TABLE_SIZE) || (err < 0)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return strerror(target_to_host_errno(err));
|
return strerror(target_to_host_errno(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user