From 530bed0ca8285188ce6cbc9406e817da0ef4828b Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sun, 14 Dec 2014 13:30:54 +0000 Subject: [PATCH] Fix decoding of getgroups, getgroups32, setgroups, and setgroups32 syscalls Convert parsers of these syscalls to the same scheme as were applied to parsers of other uid/gid related syscalls. That is, define two sets of parsers on architectures that support (either directly or via multiarch) 16-bit and 32-bit gid getgroups and setgroups syscalls simultaneously, and reuse essentially the same code by parametrizing uid_t and names of parser functions. * groups.c: Remove. (sys_getgroups, sys_setgroups): Move ... * uid.c: ... here and parametrize their names. * Makefile.am (strace_SOURCES): Remove groups.c. * linux/syscall.h (sys_getgroups32, sys_setgroups32): Remove. [NEED_UID16_PARSERS] (sys_getgroups16, sys_setgroups16): New prototypes. * linux/arm/syscallent.h: Rename sys_[gs]etgroups to sys_[gs]etgroups16, rename sys_[gs]etgroups32 to sys_[gs]etgroups. * 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/sh/syscallent.h: Likewise. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent.h: Likewise. * tests/uid.c: Test for getgroups. * tests/uid16.c: Likewise. * tests/uid32.c: Test for getgroups32. * tests/uid.awk: Test for getgroups/getgroups32 decoding. * tests/uid.test: Trace getgroups/getgroups32 syscalls. --- Makefile.am | 1 - groups.c | 237 ---------------------------------- linux/arm/syscallent.h | 8 +- linux/bfin/syscallent.h | 8 +- linux/i386/syscallent.h | 8 +- linux/m68k/syscallent.h | 8 +- linux/microblaze/syscallent.h | 8 +- linux/s390/syscallent.h | 4 +- linux/sh/syscallent.h | 8 +- linux/sh64/syscallent.h | 8 +- linux/sparc/syscallent.h | 8 +- linux/syscall.h | 4 +- tests/uid.awk | 14 ++ tests/uid.c | 11 +- tests/uid.test | 2 +- tests/uid16.c | 11 +- tests/uid32.c | 11 +- uid.c | 127 +++++++++++++++++- 18 files changed, 200 insertions(+), 286 deletions(-) delete mode 100644 groups.c diff --git a/Makefile.am b/Makefile.am index a89817cd..5a852b88 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,7 +41,6 @@ strace_SOURCES = \ get_robust_list.c \ getcpu.c \ getcwd.c \ - groups.c \ hostname.c \ inotify.c \ io.c \ diff --git a/groups.c b/groups.c deleted file mode 100644 index 2b4350c7..00000000 --- a/groups.c +++ /dev/null @@ -1,237 +0,0 @@ -#include "defs.h" - -#include -#undef GETGROUPS_T -#define GETGROUPS_T __kernel_gid_t -#undef GETGROUPS32_T -#define GETGROUPS32_T __kernel_gid32_t - -int -sys_setgroups(struct tcb *tcp) -{ - if (entering(tcp)) { - unsigned long len, size, start, cur, end, abbrev_end; - GETGROUPS_T gid; - int failed = 0; - - len = tcp->u_arg[0]; - tprintf("%lu, ", len); - if (len == 0) { - tprints("[]"); - return 0; - } - start = tcp->u_arg[1]; - if (start == 0) { - tprints("NULL"); - return 0; - } - size = len * sizeof(gid); - end = start + size; - if (!verbose(tcp) || size / sizeof(gid) != len || end < start) { - tprintf("%#lx", start); - return 0; - } - if (abbrev(tcp)) { - abbrev_end = start + max_strlen * sizeof(gid); - if (abbrev_end < start) - abbrev_end = end; - } else { - abbrev_end = end; - } - tprints("["); - for (cur = start; cur < end; cur += sizeof(gid)) { - if (cur > start) - tprints(", "); - if (cur >= abbrev_end) { - tprints("..."); - break; - } - if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { - tprints("?"); - failed = 1; - break; - } - tprintf("%lu", (unsigned long) gid); - } - tprints("]"); - if (failed) - tprintf(" %#lx", tcp->u_arg[1]); - } - return 0; -} - -int -sys_getgroups(struct tcb *tcp) -{ - unsigned long len; - - if (entering(tcp)) { - len = tcp->u_arg[0]; - tprintf("%lu, ", len); - } else { - unsigned long size, start, cur, end, abbrev_end; - GETGROUPS_T gid; - int failed = 0; - - len = tcp->u_rval; - if (len == 0) { - tprints("[]"); - return 0; - } - start = tcp->u_arg[1]; - if (start == 0) { - tprints("NULL"); - return 0; - } - if (tcp->u_arg[0] == 0) { - tprintf("%#lx", start); - return 0; - } - size = len * sizeof(gid); - end = start + size; - if (!verbose(tcp) || tcp->u_arg[0] == 0 || - size / sizeof(gid) != len || end < start) { - tprintf("%#lx", start); - return 0; - } - if (abbrev(tcp)) { - abbrev_end = start + max_strlen * sizeof(gid); - if (abbrev_end < start) - abbrev_end = end; - } else { - abbrev_end = end; - } - tprints("["); - for (cur = start; cur < end; cur += sizeof(gid)) { - if (cur > start) - tprints(", "); - if (cur >= abbrev_end) { - tprints("..."); - break; - } - if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { - tprints("?"); - failed = 1; - break; - } - tprintf("%lu", (unsigned long) gid); - } - tprints("]"); - if (failed) - tprintf(" %#lx", tcp->u_arg[1]); - } - return 0; -} - -int -sys_setgroups32(struct tcb *tcp) -{ - if (entering(tcp)) { - unsigned long len, size, start, cur, end, abbrev_end; - GETGROUPS32_T gid; - int failed = 0; - - len = tcp->u_arg[0]; - tprintf("%lu, ", len); - if (len == 0) { - tprints("[]"); - return 0; - } - start = tcp->u_arg[1]; - if (start == 0) { - tprints("NULL"); - return 0; - } - size = len * sizeof(gid); - end = start + size; - if (!verbose(tcp) || size / sizeof(gid) != len || end < start) { - tprintf("%#lx", start); - return 0; - } - if (abbrev(tcp)) { - abbrev_end = start + max_strlen * sizeof(gid); - if (abbrev_end < start) - abbrev_end = end; - } else { - abbrev_end = end; - } - tprints("["); - for (cur = start; cur < end; cur += sizeof(gid)) { - if (cur > start) - tprints(", "); - if (cur >= abbrev_end) { - tprints("..."); - break; - } - if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { - tprints("?"); - failed = 1; - break; - } - tprintf("%lu", (unsigned long) gid); - } - tprints("]"); - if (failed) - tprintf(" %#lx", tcp->u_arg[1]); - } - return 0; -} - -int -sys_getgroups32(struct tcb *tcp) -{ - unsigned long len; - - if (entering(tcp)) { - len = tcp->u_arg[0]; - tprintf("%lu, ", len); - } else { - unsigned long size, start, cur, end, abbrev_end; - GETGROUPS32_T gid; - int failed = 0; - - len = tcp->u_rval; - if (len == 0) { - tprints("[]"); - return 0; - } - start = tcp->u_arg[1]; - if (start == 0) { - tprints("NULL"); - return 0; - } - size = len * sizeof(gid); - end = start + size; - if (!verbose(tcp) || tcp->u_arg[0] == 0 || - size / sizeof(gid) != len || end < start) { - tprintf("%#lx", start); - return 0; - } - if (abbrev(tcp)) { - abbrev_end = start + max_strlen * sizeof(gid); - if (abbrev_end < start) - abbrev_end = end; - } else { - abbrev_end = end; - } - tprints("["); - for (cur = start; cur < end; cur += sizeof(gid)) { - if (cur > start) - tprints(", "); - if (cur >= abbrev_end) { - tprints("..."); - break; - } - if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { - tprints("?"); - failed = 1; - break; - } - tprintf("%lu", (unsigned long) gid); - } - tprints("]"); - if (failed) - tprintf(" %#lx", tcp->u_arg[1]); - } - return 0; -} diff --git a/linux/arm/syscallent.h b/linux/arm/syscallent.h index 0436a513..6dff25e8 100644 --- a/linux/arm/syscallent.h +++ b/linux/arm/syscallent.h @@ -106,8 +106,8 @@ { 2, 0, sys_getrusage, "getrusage" }, /* 77 */ { 2, 0, sys_gettimeofday, "gettimeofday" }, /* 78 */ { 2, 0, sys_settimeofday, "settimeofday" }, /* 79 */ - { 2, 0, sys_getgroups, "getgroups" }, /* 80 */ - { 2, 0, sys_setgroups, "setgroups" }, /* 81 */ + { 2, 0, sys_getgroups16, "getgroups" }, /* 80 */ + { 2, 0, sys_setgroups16, "setgroups" }, /* 81 */ { 1, TD, sys_oldselect, "oldselect" }, /* 82 */ { 2, TF, sys_symlink, "symlink" }, /* 83 */ { 2, TF, sys_oldlstat, "oldlstat" }, /* 84 */ @@ -233,8 +233,8 @@ { 0, NF, sys_geteuid, "getegid32" }, /* 202 */ { 2, 0, sys_setreuid, "setreuid32" }, /* 203 */ { 2, 0, sys_setregid, "setregid32" }, /* 204 */ - { 2, 0, sys_getgroups32, "getgroups32" }, /* 205 */ - { 2, 0, sys_setgroups32, "setgroups32" }, /* 206 */ + { 2, 0, sys_getgroups, "getgroups32" }, /* 205 */ + { 2, 0, sys_setgroups, "setgroups32" }, /* 206 */ { 3, TD, sys_fchown, "fchown32" }, /* 207 */ { 3, 0, sys_setresuid, "setresuid32" }, /* 208 */ { 3, 0, sys_getresuid, "getresuid32" }, /* 209 */ diff --git a/linux/bfin/syscallent.h b/linux/bfin/syscallent.h index 79f054a7..8200d44f 100644 --- a/linux/bfin/syscallent.h +++ b/linux/bfin/syscallent.h @@ -106,8 +106,8 @@ { 2, 0, sys_getrusage, "getrusage" }, /* 77 */ { 2, 0, sys_gettimeofday, "gettimeofday" }, /* 78 */ { 2, 0, sys_settimeofday, "settimeofday" }, /* 79 */ - { 2, 0, sys_getgroups, "getgroups" }, /* 80 */ - { 2, 0, sys_setgroups, "setgroups" }, /* 81 */ + { 2, 0, sys_getgroups16, "getgroups" }, /* 80 */ + { 2, 0, sys_setgroups16, "setgroups" }, /* 81 */ { 1, TD, sys_oldselect, "oldselect" }, /* 82 */ { 2, TF, sys_symlink, "symlink" }, /* 83 */ { 2, TF, sys_oldlstat, "oldlstat" }, /* 84 */ @@ -231,8 +231,8 @@ { 0, NF, sys_geteuid, "getegid32" }, /* 202 */ { 2, 0, sys_setreuid, "setreuid32" }, /* 203 */ { 2, 0, sys_setregid, "setregid32" }, /* 204 */ - { 2, 0, sys_getgroups32, "getgroups32" }, /* 205 */ - { 2, 0, sys_setgroups32, "setgroups32" }, /* 206 */ + { 2, 0, sys_getgroups, "getgroups32" }, /* 205 */ + { 2, 0, sys_setgroups, "setgroups32" }, /* 206 */ { 3, TD, sys_fchown, "fchown32" }, /* 207 */ { 3, 0, sys_setresuid, "setresuid32" }, /* 208 */ { 3, 0, sys_getresuid, "getresuid32" }, /* 209 */ diff --git a/linux/i386/syscallent.h b/linux/i386/syscallent.h index 2ed37230..fea5a25d 100644 --- a/linux/i386/syscallent.h +++ b/linux/i386/syscallent.h @@ -106,8 +106,8 @@ { 2, 0, sys_getrusage, "getrusage" }, /* 77 */ { 2, 0, sys_gettimeofday, "gettimeofday" }, /* 78 */ { 2, 0, sys_settimeofday, "settimeofday" }, /* 79 */ - { 2, 0, sys_getgroups, "getgroups" }, /* 80 */ - { 2, 0, sys_setgroups, "setgroups" }, /* 81 */ + { 2, 0, sys_getgroups16, "getgroups" }, /* 80 */ + { 2, 0, sys_setgroups16, "setgroups" }, /* 81 */ { 1, TD, sys_oldselect, "oldselect" }, /* 82 */ { 2, TF, sys_symlink, "symlink" }, /* 83 */ { 2, TF, sys_oldlstat, "oldlstat" }, /* 84 */ @@ -233,8 +233,8 @@ { 0, NF, sys_getegid, "getegid32" }, /* 202 */ { 2, 0, sys_setreuid, "setreuid32" }, /* 203 */ { 2, 0, sys_setregid, "setregid32" }, /* 204 */ - { 2, 0, sys_getgroups32, "getgroups32" }, /* 205 */ - { 2, 0, sys_setgroups32, "setgroups32" }, /* 206 */ + { 2, 0, sys_getgroups, "getgroups32" }, /* 205 */ + { 2, 0, sys_setgroups, "setgroups32" }, /* 206 */ { 3, TD, sys_fchown, "fchown32" }, /* 207 */ { 3, 0, sys_setresuid, "setresuid32" }, /* 208 */ { 3, 0, sys_getresuid, "getresuid32" }, /* 209 */ diff --git a/linux/m68k/syscallent.h b/linux/m68k/syscallent.h index 03257bd1..155f01cf 100644 --- a/linux/m68k/syscallent.h +++ b/linux/m68k/syscallent.h @@ -106,8 +106,8 @@ { 2, 0, sys_getrusage, "getrusage" }, /* 77 */ { 2, 0, sys_gettimeofday, "gettimeofday" }, /* 78 */ { 2, 0, sys_settimeofday, "settimeofday" }, /* 79 */ - { 2, 0, sys_getgroups, "getgroups" }, /* 80 */ - { 2, 0, sys_setgroups, "setgroups" }, /* 81 */ + { 2, 0, sys_getgroups16, "getgroups" }, /* 80 */ + { 2, 0, sys_setgroups16, "setgroups" }, /* 81 */ { 1, TD, sys_oldselect, "oldselect" }, /* 82 */ { 2, TF, sys_symlink, "symlink" }, /* 83 */ { 2, TF, sys_oldlstat, "oldlstat" }, /* 84 */ @@ -231,8 +231,8 @@ { 0, NF, sys_geteuid, "getegid32" }, /* 202 */ { 2, 0, sys_setreuid, "setreuid32" }, /* 203 */ { 2, 0, sys_setregid, "setregid32" }, /* 204 */ - { 2, 0, sys_getgroups32, "getgroups32" }, /* 205 */ - { 2, 0, sys_setgroups32, "setgroups32" }, /* 206 */ + { 2, 0, sys_getgroups, "getgroups32" }, /* 205 */ + { 2, 0, sys_setgroups, "setgroups32" }, /* 206 */ { 3, TD, sys_fchown, "fchown32" }, /* 207 */ { 3, 0, sys_setresuid, "setresuid32" }, /* 208 */ { 3, 0, sys_getresuid, "getresuid32" }, /* 209 */ diff --git a/linux/microblaze/syscallent.h b/linux/microblaze/syscallent.h index 629c1876..2f50eaed 100644 --- a/linux/microblaze/syscallent.h +++ b/linux/microblaze/syscallent.h @@ -106,8 +106,8 @@ { 2, 0, sys_getrusage, "getrusage" }, /* 77 */ { 2, 0, sys_gettimeofday, "gettimeofday" }, /* 78 */ { 2, 0, sys_settimeofday, "settimeofday" }, /* 79 */ - { 2, 0, sys_getgroups, "getgroups" }, /* 80 */ - { 2, 0, sys_setgroups, "setgroups" }, /* 81 */ + { 2, 0, sys_getgroups16, "getgroups" }, /* 80 */ + { 2, 0, sys_setgroups16, "setgroups" }, /* 81 */ { 1, TD, sys_oldselect, "oldselect" }, /* 82 */ { 2, TF, sys_symlink, "symlink" }, /* 83 */ { 2, TF, sys_oldlstat, "oldlstat" }, /* 84 */ @@ -231,8 +231,8 @@ { 0, NF, sys_geteuid, "getegid32" }, /* 202 */ { 2, 0, sys_setreuid, "setreuid32" }, /* 203 */ { 2, 0, sys_setregid, "setregid32" }, /* 204 */ - { 2, 0, sys_getgroups32, "getgroups32" }, /* 205 */ - { 2, 0, sys_setgroups32, "setgroups32" }, /* 206 */ + { 2, 0, sys_getgroups, "getgroups32" }, /* 205 */ + { 2, 0, sys_setgroups, "setgroups32" }, /* 206 */ { 3, TD, sys_fchown, "fchown32" }, /* 207 */ { 3, 0, sys_setresuid, "setresuid32" }, /* 208 */ { 3, 0, sys_getresuid, "getresuid32" }, /* 209 */ diff --git a/linux/s390/syscallent.h b/linux/s390/syscallent.h index a2c9d10a..26dc35a9 100644 --- a/linux/s390/syscallent.h +++ b/linux/s390/syscallent.h @@ -108,8 +108,8 @@ { 2, 0, sys_getrusage, "getrusage" }, /* 77 */ { 2, 0, sys_gettimeofday, "gettimeofday" }, /* 78 */ { 2, 0, sys_settimeofday, "settimeofday" }, /* 79 */ - { 2, 0, sys_getgroups, "getgroups" }, /* 80 */ - { 2, 0, sys_setgroups, "setgroups" }, /* 81 */ + { 2, 0, sys_getgroups16, "getgroups" }, /* 80 */ + { 2, 0, sys_setgroups16, "setgroups" }, /* 81 */ { MA, 0, NULL, NULL }, /* 82 */ { 2, TF, sys_symlink, "symlink" }, /* 83 */ { MA, 0, NULL, NULL }, /* 84 */ diff --git a/linux/sh/syscallent.h b/linux/sh/syscallent.h index 13a2f62b..8aa386ed 100644 --- a/linux/sh/syscallent.h +++ b/linux/sh/syscallent.h @@ -108,8 +108,8 @@ { 2, 0, sys_getrusage, "getrusage" }, /* 77 */ { 2, 0, sys_gettimeofday, "gettimeofday" }, /* 78 */ { 2, 0, sys_settimeofday, "settimeofday" }, /* 79 */ - { 2, 0, sys_getgroups, "getgroups" }, /* 80 */ - { 2, 0, sys_setgroups, "setgroups" }, /* 81 */ + { 2, 0, sys_getgroups16, "getgroups" }, /* 80 */ + { 2, 0, sys_setgroups16, "setgroups" }, /* 81 */ { 1, TD, sys_oldselect, "oldselect" }, /* 82 */ { 2, TF, sys_symlink, "symlink" }, /* 83 */ { 2, TF, sys_oldlstat, "oldlstat" }, /* 84 */ @@ -233,8 +233,8 @@ { 0, 0, sys_getegid, "getegid32" }, /* 202 */ { 2, 0, sys_setreuid, "setreuid32" }, /* 203 */ { 2, 0, sys_setregid, "setregid32" }, /* 204 */ - { 2, 0, sys_getgroups32, "getgroups32" }, /* 205 */ - { 2, 0, sys_setgroups32, "setgroups32" }, /* 206 */ + { 2, 0, sys_getgroups, "getgroups32" }, /* 205 */ + { 2, 0, sys_setgroups, "setgroups32" }, /* 206 */ { 3, 0, sys_fchown, "fchown32" }, /* 207 */ { 3, 0, sys_setresuid, "setresuid32" }, /* 208 */ { 3, 0, sys_getresuid, "getresuid32" }, /* 209 */ diff --git a/linux/sh64/syscallent.h b/linux/sh64/syscallent.h index db43bfc9..bb5bb8ec 100644 --- a/linux/sh64/syscallent.h +++ b/linux/sh64/syscallent.h @@ -106,8 +106,8 @@ { 2, 0, sys_getrusage, "getrusage" }, /* 77 */ { 2, 0, sys_gettimeofday, "gettimeofday" }, /* 78 */ { 2, 0, sys_settimeofday, "settimeofday" }, /* 79 */ - { 2, 0, sys_getgroups, "getgroups" }, /* 80 */ - { 2, 0, sys_setgroups, "setgroups" }, /* 81 */ + { 2, 0, sys_getgroups16, "getgroups" }, /* 80 */ + { 2, 0, sys_setgroups16, "setgroups" }, /* 81 */ { 1, TD, sys_oldselect, "oldselect" }, /* 82 */ { 2, TF, sys_symlink, "symlink" }, /* 83 */ { 2, TF, sys_oldlstat, "oldlstat" }, /* 84 */ @@ -231,8 +231,8 @@ { 0, 0, sys_getegid, "getegid32" }, /* 202 */ { 2, 0, sys_setreuid, "setreuid32" }, /* 203 */ { 2, 0, sys_setregid, "setregid32" }, /* 204 */ - { 2, 0, sys_getgroups32, "getgroups32" }, /* 205 */ - { 2, 0, sys_setgroups32, "setgroups32" }, /* 206 */ + { 2, 0, sys_getgroups, "getgroups32" }, /* 205 */ + { 2, 0, sys_setgroups, "setgroups32" }, /* 206 */ { 3, 0, sys_fchown, "fchown32" }, /* 207 */ { 3, 0, sys_setresuid, "setresuid32" }, /* 208 */ { 3, 0, sys_getresuid, "getresuid32" }, /* 209 */ diff --git a/linux/sparc/syscallent.h b/linux/sparc/syscallent.h index 39d2ad04..a194d5f9 100644 --- a/linux/sparc/syscallent.h +++ b/linux/sparc/syscallent.h @@ -77,10 +77,10 @@ { 0, 0, sys_vhangup, "vhangup" }, /* 76 */ { 3, TF, sys_truncate64, "truncate64" }, /* 77 */ { 3, TM, sys_mincore, "mincore" }, /* 78 */ - { 2, 0, sys_getgroups, "getgroups" }, /* 79 */ - { 2, 0, sys_setgroups, "setgroups" }, /* 80 */ + { 2, 0, sys_getgroups16,"getgroups" }, /* 79 */ + { 2, 0, sys_setgroups16,"setgroups" }, /* 80 */ { 0, 0, sys_getpgrp, "getpgrp" }, /* 81 */ - { 2, 0, sys_setgroups32,"setgroups32" }, /* 82 */ + { 2, 0, sys_setgroups, "setgroups32" }, /* 82 */ { 3, 0, sys_setitimer, "setitimer" }, /* 83 */ { 3, TD, sys_ftruncate64,"ftruncate64" }, /* 84 */ { 2, TF, sys_swapon, "swapon" }, /* 85 */ @@ -113,7 +113,7 @@ { 2, 0, sys_setregid, "setregid32" }, /* 112 */ { 3, TN, sys_recvmsg, "recvmsg" }, /* 113 */ { 3, TN, sys_sendmsg, "sendmsg" }, /* 114 */ - { 2, 0, sys_getgroups32,"getgroups32" }, /* 115 */ + { 2, 0, sys_getgroups, "getgroups32" }, /* 115 */ { 2, 0, sys_gettimeofday,"gettimeofday" }, /* 116 */ { 2, 0, sys_getrusage, "getrusage" }, /* 117 */ { 5, TN, sys_getsockopt, "getsockopt" }, /* 118 */ diff --git a/linux/syscall.h b/linux/syscall.h index 5bfb19c6..d353f746 100644 --- a/linux/syscall.h +++ b/linux/syscall.h @@ -100,7 +100,6 @@ int sys_getdents(); int sys_getdents64(); int sys_getdtablesize(); int sys_getgroups(); -int sys_getgroups32(); int sys_gethostname(); int sys_getitimer(); int sys_getpmsg(); /* TODO: non-Linux, remove? */ @@ -237,7 +236,6 @@ int sys_set_mempolicy(); int sys_set_thread_area(); int sys_setfsuid(); int sys_setgroups(); -int sys_setgroups32(); int sys_sethostname(); int sys_setitimer(); int sys_setns(); @@ -357,9 +355,11 @@ int sys_putmsg(); #if NEED_UID16_PARSERS int sys_chown16(); int sys_fchown16(); +int sys_getgroups16(); int sys_getresuid16(); int sys_getuid16(); int sys_setfsuid16(); +int sys_setgroups16(); int sys_setresuid16(); int sys_setreuid16(); int sys_setuid16(); diff --git a/tests/uid.awk b/tests/uid.awk index d5e350c2..e8d68248 100644 --- a/tests/uid.awk +++ b/tests/uid.awk @@ -35,6 +35,20 @@ regexp == "" { regexp = "^chown" suffix "\\(\".\", -1, -1\\)[[:space:]]+= 0$" next case "chown": + expected = "1st getgroups" + regexp = "^getgroups" suffix "\\(0, NULL\\)[[:space:]]+= " r_uint "$" + next + case "1st getgroups": + ngroups = a[1] + switch (ngroups) { + case "0": list=""; break + case "1": list=r_uint; break + default: list=r_uint "(, " r_uint "){" (ngroups - 1) "}" + } + expected = "2nd getgroups" + regexp = "^getgroups" suffix "\\(" ngroups ", \\[" list "\\]\\)[[:space:]]+= " ngroups "$" + next + case "2nd getgroups": expected = "the last line" regexp = "^\\+\\+\\+ exited with 0 \\+\\+\\+$" next diff --git a/tests/uid.c b/tests/uid.c index b4b98139..5687dabd 100644 --- a/tests/uid.c +++ b/tests/uid.c @@ -2,6 +2,7 @@ # include "config.h" #endif #include +#include #include #include @@ -13,8 +14,11 @@ main(void) && defined(__NR_getresuid) \ && defined(__NR_setreuid) \ && defined(__NR_setresuid) \ - && defined(__NR_chown) - uid_t r, e, s; + && defined(__NR_chown) \ + && defined(__NR_getgroups) + int r, e, s; + int size; + int *list = 0; e = syscall(__NR_getuid); assert(syscall(__NR_setuid, e) == 0); @@ -22,6 +26,9 @@ main(void) assert(syscall(__NR_setreuid, -1, -1L) == 0); assert(syscall(__NR_setresuid, -1, e, -1L) == 0); assert(syscall(__NR_chown, ".", -1, -1L) == 0); + assert((size = syscall(__NR_getgroups, 0, list)) >= 0); + assert(list = calloc(size + 1, sizeof(*list))); + assert(syscall(__NR_getgroups, size, list) == size); return 0; #else return 77; diff --git a/tests/uid.test b/tests/uid.test index 02fea2aa..e711350b 100755 --- a/tests/uid.test +++ b/tests/uid.test @@ -17,7 +17,7 @@ uid="uid$s$w" fi } -syscalls="getuid$s,setuid$s,getresuid$s,setreuid$s,setresuid$s,chown$s" +syscalls="getuid$s,setuid$s,getresuid$s,setreuid$s,setresuid$s,chown$s,getgroups$s" args="-e trace=$syscalls" $STRACE -o "$LOG" $args ./"$uid"|| { cat "$LOG" diff --git a/tests/uid16.c b/tests/uid16.c index 43960e73..820dd90d 100644 --- a/tests/uid16.c +++ b/tests/uid16.c @@ -2,6 +2,7 @@ # include "config.h" #endif #include +#include #include #include @@ -14,6 +15,7 @@ main(void) && defined(__NR_setreuid) \ && defined(__NR_setresuid) \ && defined(__NR_chown) \ + && defined(__NR_getgroups) \ \ && defined(__NR_getuid32) \ && defined(__NR_setuid32) \ @@ -21,6 +23,7 @@ main(void) && defined(__NR_setreuid32) \ && defined(__NR_setresuid32) \ && defined(__NR_chown32) \ + && defined(__NR_getgroups32) \ \ && __NR_getuid != __NR_getuid32 \ && __NR_setuid != __NR_setuid32 \ @@ -28,8 +31,11 @@ main(void) && __NR_setreuid != __NR_setreuid32 \ && __NR_setresuid != __NR_setresuid32 \ && __NR_chown != __NR_chown32 \ + && __NR_getgroups != __NR_getgroups32 \ /**/ - uid_t r, e, s; + int r, e, s; + int size; + int *list = 0; e = syscall(__NR_getuid); assert(syscall(__NR_setuid, e) == 0); @@ -37,6 +43,9 @@ main(void) assert(syscall(__NR_setreuid, -1, 0xffff) == 0); assert(syscall(__NR_setresuid, -1, e, 0xffff) == 0); assert(syscall(__NR_chown, ".", -1, 0xffff) == 0); + assert((size = syscall(__NR_getgroups, 0, list)) >= 0); + assert(list = calloc(size + 1, sizeof(*list))); + assert(syscall(__NR_getgroups, size, list) == size); return 0; #else return 77; diff --git a/tests/uid32.c b/tests/uid32.c index 94301b77..95d04ea9 100644 --- a/tests/uid32.c +++ b/tests/uid32.c @@ -2,6 +2,7 @@ # include "config.h" #endif #include +#include #include #include @@ -13,8 +14,11 @@ main(void) && defined(__NR_getresuid32) \ && defined(__NR_setreuid32) \ && defined(__NR_setresuid32) \ - && defined(__NR_chown32) - uid_t r, e, s; + && defined(__NR_chown32) \ + && defined(__NR_getgroups32) + int r, e, s; + int size; + int *list = 0; e = syscall(__NR_getuid32); assert(syscall(__NR_setuid32, e) == 0); @@ -22,6 +26,9 @@ main(void) assert(syscall(__NR_setreuid32, -1, -1L) == 0); assert(syscall(__NR_setresuid32, -1, e, -1L) == 0); assert(syscall(__NR_chown32, ".", -1, -1L) == 0); + assert((size = syscall(__NR_getgroups32, 0, list)) >= 0); + assert(list = calloc(size + 1, sizeof(*list))); + assert(syscall(__NR_getgroups32, size, list) == size); return 0; #else return 77; diff --git a/uid.c b/uid.c index 376d0591..1f8c3657 100644 --- a/uid.c +++ b/uid.c @@ -7,15 +7,17 @@ # define SIZEIFY_(x,size) SIZEIFY__(x,size) # define SIZEIFY__(x,size) x ## size +# define printuid SIZEIFY(printuid) +# define sys_chown SIZEIFY(sys_chown) +# define sys_fchown SIZEIFY(sys_fchown) +# define sys_getgroups SIZEIFY(sys_getgroups) +# define sys_getresuid SIZEIFY(sys_getresuid) # 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_setgroups SIZEIFY(sys_setgroups) # define sys_setresuid SIZEIFY(sys_setresuid) -# define sys_chown SIZEIFY(sys_chown) -# define sys_fchown SIZEIFY(sys_fchown) -# define printuid SIZEIFY(printuid) +# define sys_setreuid SIZEIFY(sys_setreuid) +# define sys_setuid SIZEIFY(sys_setuid) #endif /* STRACE_UID_SIZE */ #include "defs.h" @@ -141,4 +143,117 @@ printuid(const char *text, const unsigned int uid) tprintf("%s%u", text, uid); } +int +sys_setgroups(struct tcb *tcp) +{ + if (entering(tcp)) { + unsigned long len, size, start, cur, end, abbrev_end; + uid_t gid; + int failed = 0; + + len = tcp->u_arg[0]; + tprintf("%lu, ", len); + if (len == 0) { + tprints("[]"); + return 0; + } + start = tcp->u_arg[1]; + if (start == 0) { + tprints("NULL"); + return 0; + } + size = len * sizeof(gid); + end = start + size; + if (!verbose(tcp) || size / sizeof(gid) != len || end < start) { + tprintf("%#lx", start); + return 0; + } + if (abbrev(tcp)) { + abbrev_end = start + max_strlen * sizeof(gid); + if (abbrev_end < start) + abbrev_end = end; + } else { + abbrev_end = end; + } + tprints("["); + for (cur = start; cur < end; cur += sizeof(gid)) { + if (cur > start) + tprints(", "); + if (cur >= abbrev_end) { + tprints("..."); + break; + } + if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { + tprints("?"); + failed = 1; + break; + } + tprintf("%u", (unsigned int) gid); + } + tprints("]"); + if (failed) + tprintf(" %#lx", tcp->u_arg[1]); + } + return 0; +} + +int +sys_getgroups(struct tcb *tcp) +{ + unsigned long len; + + if (entering(tcp)) { + len = tcp->u_arg[0]; + tprintf("%lu, ", len); + } else { + unsigned long size, start, cur, end, abbrev_end; + uid_t gid; + int failed = 0; + + start = tcp->u_arg[1]; + if (start == 0) { + tprints("NULL"); + return 0; + } + len = tcp->u_rval; + if (len == 0) { + tprints("[]"); + return 0; + } + size = len * sizeof(gid); + end = start + size; + if (!verbose(tcp) || tcp->u_arg[0] == 0 || + size / sizeof(gid) != len || end < start) { + tprintf("%#lx", start); + return 0; + } + if (abbrev(tcp)) { + abbrev_end = start + max_strlen * sizeof(gid); + if (abbrev_end < start) + abbrev_end = end; + } else { + abbrev_end = end; + } + tprints("["); + for (cur = start; cur < end; cur += sizeof(gid)) { + if (cur > start) + tprints(", "); + if (cur >= abbrev_end) { + tprints("..."); + break; + } + if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) { + tprints("?"); + failed = 1; + break; + } + tprintf("%u", (unsigned int) gid); + } + tprints("]"); + if (failed) + tprintf(" %#lx", tcp->u_arg[1]); + } + return 0; +} + #endif /* STRACE_UID_SIZE */ -- 2.34.1