[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH V2] linux-user: fix QEMU_STRACE=1 segfault
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PATCH V2] linux-user: fix QEMU_STRACE=1 segfault |
Date: |
Mon, 21 Nov 2011 11:40:00 +0100 |
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 <address@hidden>
---
v1 -> v2:
- propagate fault further down, so we display the negative value
---
linux-user/strace.c | 9 +++++++--
linux-user/syscall.c | 3 +++
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 90027a1..e30b005 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1515,14 +1515,19 @@ void
print_syscall_ret(int num, abi_long ret)
{
int i;
+ char *errstr = NULL;
for(i=0;i<nsyscalls;i++)
if( scnames[i].nr == num ) {
if( scnames[i].result != NULL ) {
scnames[i].result(&scnames[i],ret);
} else {
- if( ret < 0 ) {
- gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret,
target_strerror(-ret));
+ if (ret < 0) {
+ errstr = target_strerror(-ret);
+ }
+ if (errstr) {
+ gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n",
+ -ret, errstr);
} else {
gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
}
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f227097..c59d00e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -731,6 +731,9 @@ static inline int is_error(abi_long ret)
char *target_strerror(int err)
{
+ if ((err >= ERRNO_TABLE_SIZE) && (err >= 0)) {
+ return NULL;
+ }
return strerror(target_to_host_errno(err));
}
--
1.6.0.2
- [Qemu-devel] [PATCH V2] linux-user: fix QEMU_STRACE=1 segfault,
Alexander Graf <=