diff options
author | Mike Frysinger <vapier@gentoo.org> | 2013-02-08 19:10:07 -0500 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2013-02-09 01:39:43 +0000 |
commit | 0cf04b6595a951df7671eafef5f9e7a114a6c691 (patch) | |
tree | a0d7cab133e269b2ccdb5f2f85a6cde58e749571 /system.c | |
parent | 99aa181ebcee3f6ae4f8eb83c719cc64cc5a09ec (diff) | |
download | strace-0cf04b6595a951df7671eafef5f9e7a114a6c691.tar.gz strace-0cf04b6595a951df7671eafef5f9e7a114a6c691.tar.bz2 strace-0cf04b6595a951df7671eafef5f9e7a114a6c691.tar.xz |
Fix decoding of sysctl() when oldval fields are NULL
If you call glibc's syscall wrapper like so:
static int name[] = { CTL_NET, NET_IPV4, NET_IPV4_LOCAL_PORT_RANGE };
int buffer[2] = { 32768, 61000 };
size_t size = sizeof(buffer);
sysctl(name, 3, 0, 0, buffer, size);
(note that oldval/oldlenp are NULL).
The current strace code complains like so:
_sysctl({{CTL_NET, NET_IPV4, NET_IPV4_LOCAL_PORT_RANGE, 38}, 3, process_vm_readv: Bad address
(nil), 0, 0x7fffe23c3960, 8}) = -1 EACCES (Permission denied)
Since passing NULL for the old values is valid, handle that explicitly.
This also simplifies the code a bit by splitting up the handling of the
new and old args so that we only handle the new args once.
Now the output looks like:
_sysctl({{CTL_NET, NET_IPV4, NET_IPV4_LOCAL_PORT_RANGE, 38}, 3, NULL, 0, 0x7fff8c0c91b0, 8) = -1 EACCES (Permission denied)
* system.c (sys_sysctl): Check if info.oldval is NULL first. Move the
processing of oldlen/info.newval/info.newlen out so they always get
executed. Fix the format strings so we use %lu for unsigned long rather
than a mix of %ld and %lu.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'system.c')
-rw-r--r-- | system.c | 38 |
1 files changed, 19 insertions, 19 deletions
@@ -954,32 +954,32 @@ sys_sysctl(struct tcb *tcp) tprintf("}, %d, ", info.nlen); } else { size_t oldlen = 0; - if (umove(tcp, (long)info.oldlenp, &oldlen) >= 0 - && info.nlen >= 2 - && ((name[0] == CTL_KERN - && (name[1] == KERN_OSRELEASE - || name[1] == KERN_OSTYPE + if (info.oldval == NULL) { + tprints("NULL"); + } else if (umove(tcp, (long)info.oldlenp, &oldlen) >= 0 + && info.nlen >= 2 + && ((name[0] == CTL_KERN + && (name[1] == KERN_OSRELEASE + || name[1] == KERN_OSTYPE #ifdef KERN_JAVA_INTERPRETER - || name[1] == KERN_JAVA_INTERPRETER + || name[1] == KERN_JAVA_INTERPRETER #endif #ifdef KERN_JAVA_APPLETVIEWER - || name[1] == KERN_JAVA_APPLETVIEWER + || name[1] == KERN_JAVA_APPLETVIEWER #endif - )))) { + )))) { printpath(tcp, (size_t)info.oldval); - tprintf(", %lu, ", (unsigned long)oldlen); - if (info.newval == 0) - tprints("NULL"); - else if (syserror(tcp)) - tprintf("%p", info.newval); - else - printpath(tcp, (size_t)info.newval); - tprintf(", %ld}", (unsigned long)info.newlen); } else { - tprintf("%p, %ld, %p, %ld}", - info.oldval, (unsigned long)oldlen, - info.newval, (unsigned long)info.newlen); + tprintf("%p", info.oldval); } + tprintf(", %lu, ", (unsigned long)oldlen); + if (info.newval == NULL) + tprints("NULL"); + else if (syserror(tcp)) + tprintf("%p", info.newval); + else + printpath(tcp, (size_t)info.newval); + tprintf(", %lu", (unsigned long)info.newlen); } free(name); |