]> granicus.if.org Git - sudo/commitdiff
Instead of trying to grow the buffer in make_grlist_item(), simply
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 10 Oct 2011 15:10:59 +0000 (11:10 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 10 Oct 2011 15:10:59 +0000 (11:10 -0400)
increase the total length, free the old buffer and allocate a new
one.  This is less error prone and saves us from having to adjust
all the pointers in the buffer.  This code path is only taken when
there are groups longer than the length of the user field in struct
utmp or utmpx, which should be quite rare.

plugins/sudoers/pwutil.c

index 7d719e10a129591c1064a02c133f3a34cc21e018..aac32325ac42b7ad0d59e0dd0c3a68ac565be115 100644 (file)
@@ -486,12 +486,12 @@ make_gritem(const struct group *gr, const char *name)
 }
 
 #ifdef HAVE_UTMPX_H
-# define GROUPNAME_LEN (sizeof((struct utmpx *)0)->ut_user)
+# define GROUPNAME_LEN (sizeof((struct utmpx *)0)->ut_user + 1)
 #else
 # ifdef HAVE_STRUCT_UTMP_UT_USER
-#  define GROUPNAME_LEN        (sizeof((struct utmp *)0)->ut_user)
+#  define GROUPNAME_LEN        (sizeof((struct utmp *)0)->ut_user + 1)
 # else
-#  define GROUPNAME_LEN        (sizeof((struct utmp *)0)->ut_name)
+#  define GROUPNAME_LEN        (sizeof((struct utmp *)0)->ut_name + 1)
 # endif
 #endif /* HAVE_UTMPX_H */
 
@@ -503,11 +503,15 @@ static struct cache_item *
 make_grlist_item(const char *user, GETGROUPS_T *gids, int ngids)
 {
     char *cp;
-    size_t i, nsize, ngroups = 0, total, len;
+    size_t i, nsize, ngroups, total, len;
     struct cache_item *item;
     struct group_list *grlist;
     struct group *grp;
 
+#ifdef HAVE_SETAUTHDB
+    aix_setauthdb((char *) user);
+#endif
+
     /* Allocate in one big chunk for easy freeing. */
     nsize = strlen(user) + 1;
     total = sizeof(struct cache_item) + sizeof(struct group_list) + nsize;
@@ -515,6 +519,7 @@ make_grlist_item(const char *user, GETGROUPS_T *gids, int ngids)
     total += sizeof(gid_t *) * ngids;
     total += GROUPNAME_LEN * ngids;
 
+again:
     item = emalloc(total);
     cp = (char *) item + sizeof(struct cache_item);
 
@@ -545,20 +550,18 @@ make_grlist_item(const char *user, GETGROUPS_T *gids, int ngids)
        grlist->gids[i] = gids[i];
     grlist->ngids = ngids;
 
-#ifdef HAVE_SETAUTHDB
-    aix_setauthdb((char *) user);
-#endif
     /*
-     * Resolve group names by ID and store at the end.
+     * Resolve and store group names by ID.
      */
+    ngroups = 0;
     for (i = 0; i < ngids; i++) {
        if ((grp = sudo_getgrgid(gids[i])) != NULL) {
            len = strlen(grp->gr_name) + 1;
-           if (cp - (char *)grlist + len > total) {
-               void *ptr = erealloc(grlist, total + len + GROUPNAME_LEN);
+           if (cp - (char *)item + len > total) {
                total += len + GROUPNAME_LEN;
-               cp = (char *)ptr + (cp - (char *)grlist);
-               grlist = ptr;
+               efree(item);
+               gr_delref(grp);
+               goto again;
            }
            memcpy(cp, grp->gr_name, len);
            grlist->groups[ngroups++] = cp;