From 52f4fe9db6cedfba332ee0923182f5b2e9d9673b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 22 Jun 2011 16:42:36 +0200 Subject: [PATCH] id: correct getgroups usage Signed-off-by: Denys Vlasenko --- coreutils/id.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/coreutils/id.c b/coreutils/id.c index bb950f9ec..399d25e34 100644 --- a/coreutils/id.c +++ b/coreutils/id.c @@ -117,7 +117,7 @@ static int print_user(uid_t id, const char *prefix) /* On error set *n < 0 and return >= 0 * If *n is too small, update it and return < 0 - * (ok to trash groups[] in both cases) + * (ok to trash groups[] in both cases) * Otherwise fill in groups[] and return >= 0 */ static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n) @@ -131,20 +131,19 @@ static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n) m = getgrouplist(username, rgid, groups, n); /* I guess *n < 0 might indicate error. Anyway, * malloc'ing -1 bytes won't be good, so: */ - //if (*n < 0) - // return 0; - //return m; - //commented out here, happens below anyway - } else { - /* On error -1 is returned, which ends up in *n */ - int nn = getgroups(*n, groups); - /* 0: nn <= *n, groups[] was big enough; -1 otherwise */ - m = - (nn > *n); - *n = nn; + if (*n < 0) + return 0; + return m; } - if (*n < 0) - return 0; /* error, don't return < 0! */ - return m; + + *n = getgroups(*n, groups); + if (*n >= 0) + return *n; + /* Error */ + if (errno == EINVAL) /* *n is too small? */ + *n = getgroups(0, groups); /* get needed *n */ + /* if *n >= 0, return -1 (got new *n), else return 0 (error): */ + return -(*n >= 0); } int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; @@ -214,11 +213,11 @@ int id_main(int argc UNUSED_PARAM, char **argv) /* We are supplying largish buffer, trying * to not run get_groups() twice. That might be slow * ("user database in remote SQL server" case) */ - groups = xmalloc(64 * sizeof(gid_t)); + groups = xmalloc(64 * sizeof(groups[0])); n = 64; if (get_groups(username, rgid, groups, &n) < 0) { /* Need bigger buffer after all */ - groups = xrealloc(groups, n * sizeof(gid_t)); + groups = xrealloc(groups, n * sizeof(groups[0])); get_groups(username, rgid, groups, &n); } if (n > 0) {