Fix decoding of getgroups, getgroups32, setgroups, and setgroups32 syscalls
authorDmitry V. Levin <ldv@altlinux.org>
Sun, 14 Dec 2014 13:30:54 +0000 (13:30 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 16 Dec 2014 01:09:23 +0000 (01:09 +0000)
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.

18 files changed:
Makefile.am
groups.c [deleted file]
linux/arm/syscallent.h
linux/bfin/syscallent.h
linux/i386/syscallent.h
linux/m68k/syscallent.h
linux/microblaze/syscallent.h
linux/s390/syscallent.h
linux/sh/syscallent.h
linux/sh64/syscallent.h
linux/sparc/syscallent.h
linux/syscall.h
tests/uid.awk
tests/uid.c
tests/uid.test
tests/uid16.c
tests/uid32.c
uid.c

index a89817cdc745e6ad200cdfc3581b5c7915fcc935..5a852b88228ce442b280a4f7c2989da5bde41711 100644 (file)
@@ -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 (file)
index 2b4350c..0000000
--- a/groups.c
+++ /dev/null
@@ -1,237 +0,0 @@
-#include "defs.h"
-
-#include <asm/posix_types.h>
-#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;
-}
index 0436a5134540a7a2cae51d5e78ecdfdf24a6d439..6dff25e826c0783f9fc484e968dab89433f79622 100644 (file)
        { 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 */
        { 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 */
index 79f054a7a92b30f0be8b31f8248e745b7f1dcb7d..8200d44fb3100db6acb74f4d9f9c1a09b6d0324f 100644 (file)
        { 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 */
        { 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 */
index 2ed372303f363bb828b1a043a69be380d6c26500..fea5a25d6961f1bf109822fb75bb9d4ad6f72b75 100644 (file)
        { 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 */
        { 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 */
index 03257bd168336f6617e910698db6ff330ce0b956..155f01cf7a7596beb1011e8f84634fc99fa86c2a 100644 (file)
        { 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 */
        { 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 */
index 629c18762093640f588ae6c68c0d85c0bc859f0f..2f50eaeda4c8513e1da9954223e4d774016da030 100644 (file)
        { 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 */
        { 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 */
index a2c9d10a7de96b09b4d9a2020f08de02e7c95df4..26dc35a9080255f3f25c805103adc3ee944c96de 100644 (file)
        { 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 */
index 13a2f62b7c5a2b2acf79f498cd842b834bd25893..8aa386ed9ecd1ffa8d01f8ccce7d34c163f538b0 100644 (file)
        { 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 */
        { 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 */
index db43bfc9cb0c2e2d72b3b0a83e6ffdcbfa552ff8..bb5bb8eca0c023c45f97d86236718efd10162885 100644 (file)
        { 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 */
        { 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 */
index 39d2ad04e018ed408d08a32663b252adcf8e970b..a194d5f98c593b7aaa634fafa91d3d53f93668f4 100644 (file)
        { 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 */
        { 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 */
index 5bfb19c657a507ed9d184d90956728d17bcb356d..d353f74664e094ed341814e69b416097a6dae3e3 100644 (file)
@@ -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();
index d5e350c28b6353997b8b19e7df5288cf52017da8..e8d682483005f7f3322759ccceff477c3503d303 100644 (file)
@@ -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
index b4b981392fc9db86dccd8c5e2d3b27209ccbf9ac..5687dabde3a0cd5e4289ff42cb2578c82405b9b2 100644 (file)
@@ -2,6 +2,7 @@
 # include "config.h"
 #endif
 #include <assert.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include <sys/syscall.h>
 
@@ -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;
index 02fea2aa78c2732ee12e4858d3eb690a97fd5d7f..e711350b73c7a71663025fa543497c9445e05d1a 100755 (executable)
@@ -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"
index 43960e7385c78e18b2e7c1d914b1fac74f9ac1f2..820dd90d4f8905b7eb6b0805de9414a4172ecd78 100644 (file)
@@ -2,6 +2,7 @@
 # include "config.h"
 #endif
 #include <assert.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include <sys/syscall.h>
 
@@ -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;
index 94301b775d4a5b1e64957c75062da834a88d63eb..95d04ea9d4fec5fdbe61e0548f0a10f4db04581c 100644 (file)
@@ -2,6 +2,7 @@
 # include "config.h"
 #endif
 #include <assert.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include <sys/syscall.h>
 
@@ -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 376d0591ae69e4ee1ab9cc21a2ed31e69ec0d429..1f8c365704551f61a81eb22a268b54fc122d34c7 100644 (file)
--- 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 */