Fix decoding of 16-bit *chown and [gs]et*[gu]id syscalls
Define two sets of parsers on architectures that support (either
directly or via multiarch) 16-bit and 32-bit uid/gid syscalls
simultaneously. Since the code in these two sets is essentially
the same and the key difference between them is the size of uid_t,
implement it by parametrizing uid_t and names of parser functions.
* defs.h (NEED_UID16_PARSERS): New macro.
* linux/syscall.h [NEED_UID16_PARSERS] (sys_chown16, sys_fchown16,
sys_getresuid16, sys_getuid16, sys_setfsuid16, sys_setresuid16,
sys_setreuid16, sys_setuid16): New prototypes.
* linux/dummy.h (sys_geteuid16): Alias to sys_getuid16.
(sys_getegid16, sys_getgid16, sys_getresgid16, sys_setfsgid16,
sys_setgid16, sys_setregid16, sys_setresgid16): Alias to corresponding
sys_*uid16 functions.
* uid.c: Stop including <asm/posix_types.h>.
Parametrize uid_t and names of all exported functions.
(get_print_uid): New function.
(sys_getresuid): Use it.
(printuid): Check for (uid_t) -1.
* uid16.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* linux/arm/syscallent.h: Use sys_chown16, sys_fchown16, sys_getegid16,
sys_geteuid16, sys_getgid16, sys_getresgid16, sys_getresuid16,
sys_getuid16, sys_setfsgid16, sys_setfsuid16, sys_setgid16,
sys_setregid16, sys_setresgid16, sys_setresuid16, sys_setreuid16,
and sys_setuid16 parsers for *chown and [gs]et*[gu]id syscall entries.
* linux/bfin/syscallent.h: Likewise.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/microblaze/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* tests/uid16.c: New file.
* tests/uid16.test: New test.
* tests/Makefile.am (CHECK_PROGRAMS): Add uid16.
(TESTS): Add uid16.test.
* tests/.gitignore: Add uid16.
diff --git a/uid.c b/uid.c
index bab6c5e..376d059 100644
--- a/uid.c
+++ b/uid.c
@@ -1,6 +1,39 @@
+#ifdef STRACE_UID_SIZE
+# if STRACE_UID_SIZE != 16
+# error invalid STRACE_UID_SIZE
+# endif
+
+# define SIZEIFY(x) SIZEIFY_(x,STRACE_UID_SIZE)
+# define SIZEIFY_(x,size) SIZEIFY__(x,size)
+# define SIZEIFY__(x,size) x ## size
+
+# define sys_getuid SIZEIFY(sys_getuid)
+# define sys_setfsuid SIZEIFY(sys_setfsuid)
+# define sys_setuid SIZEIFY(sys_setuid)
+# define sys_getresuid SIZEIFY(sys_getresuid)
+# define sys_setreuid SIZEIFY(sys_setreuid)
+# define sys_setresuid SIZEIFY(sys_setresuid)
+# define sys_chown SIZEIFY(sys_chown)
+# define sys_fchown SIZEIFY(sys_fchown)
+# define printuid SIZEIFY(printuid)
+#endif /* STRACE_UID_SIZE */
+
#include "defs.h"
-#include <asm/posix_types.h>
+#ifdef STRACE_UID_SIZE
+# if !NEED_UID16_PARSERS
+# undef STRACE_UID_SIZE
+# endif
+#else
+# define STRACE_UID_SIZE 32
+#endif
+
+#ifdef STRACE_UID_SIZE
+
+# undef uid_t
+# define uid_t uid_t_(STRACE_UID_SIZE)
+# define uid_t_(size) uid_t__(size)
+# define uid_t__(size) uint ## size ## _t
int
sys_getuid(struct tcb *tcp)
@@ -29,27 +62,28 @@
return 0;
}
+static void
+get_print_uid(struct tcb *tcp, const char *prefix, const long addr)
+{
+ uid_t uid;
+
+ if (umove(tcp, addr, &uid) < 0)
+ tprintf("%s%#lx", prefix, addr);
+ else
+ tprintf("%s[%u]", prefix, uid);
+}
+
int
sys_getresuid(struct tcb *tcp)
{
if (exiting(tcp)) {
- __kernel_uid_t uid;
- if (syserror(tcp))
+ if (syserror(tcp)) {
tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
tcp->u_arg[1], tcp->u_arg[2]);
- else {
- if (umove(tcp, tcp->u_arg[0], &uid) < 0)
- tprintf("%#lx, ", tcp->u_arg[0]);
- else
- tprintf("[%lu], ", (unsigned long) uid);
- if (umove(tcp, tcp->u_arg[1], &uid) < 0)
- tprintf("%#lx, ", tcp->u_arg[1]);
- else
- tprintf("[%lu], ", (unsigned long) uid);
- if (umove(tcp, tcp->u_arg[2], &uid) < 0)
- tprintf("%#lx", tcp->u_arg[2]);
- else
- tprintf("[%lu]", (unsigned long) uid);
+ } else {
+ get_print_uid(tcp, "", tcp->u_arg[0]);
+ get_print_uid(tcp, ", ", tcp->u_arg[1]);
+ get_print_uid(tcp, ", ", tcp->u_arg[2]);
}
}
return 0;
@@ -101,8 +135,10 @@
void
printuid(const char *text, const unsigned int uid)
{
- if ((unsigned int) -1 == uid)
+ if ((unsigned int) -1 == uid || (uid_t) -1 == uid)
tprintf("%s-1", text);
else
tprintf("%s%u", text, uid);
}
+
+#endif /* STRACE_UID_SIZE */