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.
This commit is contained in:
Todd C. Miller
2011-10-10 11:10:59 -04:00
parent dd3902e115
commit a6602fa0e4

View 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;