From a6602fa0e4b059215027bf23f84b9da02b3dfa6f Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 10 Oct 2011 11:10:59 -0400 Subject: [PATCH] Instead of trying to grow the buffer in make_grlist_item(), simply 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 | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/plugins/sudoers/pwutil.c b/plugins/sudoers/pwutil.c index 7d719e10a..aac32325a 100644 --- a/plugins/sudoers/pwutil.c +++ b/plugins/sudoers/pwutil.c @@ -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; -- 2.40.0