From: Todd C. Miller Date: Fri, 13 Apr 2018 16:49:05 +0000 (-0600) Subject: Fix a user after free crash as well as a memory leak when filtering X-Git-Tag: SUDO_1_8_23^2~33 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=38ff6616214c68d045b4e71e7a5e25e7f949e21e;p=sudo Fix a user after free crash as well as a memory leak when filtering Defaults. --- diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c index 0fac62c3b..27dd59e48 100644 --- a/plugins/sudoers/cvtsudoers.c +++ b/plugins/sudoers/cvtsudoers.c @@ -1048,16 +1048,15 @@ filter_defaults(struct cvtsudoers_config *conf) struct member_list host_aliases = TAILQ_HEAD_INITIALIZER(host_aliases); struct member_list cmnd_aliases = TAILQ_HEAD_INITIALIZER(cmnd_aliases); struct member_list *prev_binding = NULL; - struct defaults *def; - struct member *m; - void *next; + struct defaults *def, *def_next; + struct member *m, *m_next; int alias_type; debug_decl(filter_defaults, SUDOERS_DEBUG_DEFAULTS) if (filters == NULL && conf->defaults == CVT_DEFAULTS_ALL) debug_return; - TAILQ_FOREACH_SAFE(def, &defaults, entries, next) { + TAILQ_FOREACH_SAFE(def, &defaults, entries, def_next) { bool keep = true; switch (def->type) { @@ -1097,7 +1096,7 @@ filter_defaults(struct cvtsudoers_config *conf) /* Look for aliases used by the binding. */ /* XXX - move to function */ if (alias_type != UNSPEC && def->binding != prev_binding) { - TAILQ_FOREACH_SAFE(m, def->binding, entries, next) { + TAILQ_FOREACH_SAFE(m, def->binding, entries, m_next) { if (m->type == ALIAS) { TAILQ_REMOVE(def->binding, m, entries); switch (alias_type) { @@ -1122,6 +1121,15 @@ filter_defaults(struct cvtsudoers_config *conf) } TAILQ_REMOVE(&defaults, def, entries); free_default(def, &prev_binding); + if (prev_binding != NULL) { + /* Remove and free Defaults that share the same binding. */ + while (def_next != NULL && def_next->binding == prev_binding) { + def = def_next; + def_next = TAILQ_NEXT(def, entries); + TAILQ_REMOVE(&defaults, def, entries); + free_default(def, &prev_binding); + } + } } else { prev_binding = def->binding; } @@ -1130,21 +1138,25 @@ filter_defaults(struct cvtsudoers_config *conf) /* Remove now-unreferenced aliases. */ alias_used_by_userspecs(&user_aliases, &runas_aliases, &host_aliases, &cmnd_aliases); - TAILQ_FOREACH_SAFE(m, &user_aliases, entries, next) { + TAILQ_FOREACH_SAFE(m, &user_aliases, entries, m_next) { struct alias *a = alias_remove(m->name, USERALIAS); alias_free(a); + free_member(m); } - TAILQ_FOREACH_SAFE(m, &runas_aliases, entries, next) { + TAILQ_FOREACH_SAFE(m, &runas_aliases, entries, m_next) { struct alias *a = alias_remove(m->name, RUNASALIAS); alias_free(a); + free_member(m); } - TAILQ_FOREACH_SAFE(m, &host_aliases, entries, next) { + TAILQ_FOREACH_SAFE(m, &host_aliases, entries, m_next) { struct alias *a = alias_remove(m->name, HOSTALIAS); alias_free(a); + free_member(m); } - TAILQ_FOREACH_SAFE(m, &cmnd_aliases, entries, next) { + TAILQ_FOREACH_SAFE(m, &cmnd_aliases, entries, m_next) { struct alias *a = alias_remove(m->name, CMNDALIAS); alias_free(a); + free_member(m); } debug_return; diff --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c index a88dea3a6..c0ef367c1 100644 --- a/plugins/sudoers/gram.c +++ b/plugins/sudoers/gram.c @@ -878,8 +878,10 @@ free_default(struct defaults *def, struct member_list **binding) if (def->binding != *binding) { *binding = def->binding; - free_members(def->binding); - free(def->binding); + if (def->binding != NULL) { + free_members(def->binding); + free(def->binding); + } } rcstr_delref(def->file); free(def->var); @@ -1044,7 +1046,7 @@ init_options(struct command_options *opts) opts->limitprivs = NULL; #endif } -#line 995 "gram.c" +#line 997 "gram.c" /* allocate initial stack or double stack size, up to YYMAXDEPTH */ #if defined(__cplusplus) || defined(__STDC__) static int yygrowstack(void) @@ -2169,7 +2171,7 @@ case 116: } } break; -#line 2120 "gram.c" +#line 2122 "gram.c" } yyssp -= yym; yystate = *yyssp; diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y index a6556ec47..489c98f0f 100644 --- a/plugins/sudoers/gram.y +++ b/plugins/sudoers/gram.y @@ -1106,8 +1106,10 @@ free_default(struct defaults *def, struct member_list **binding) if (def->binding != *binding) { *binding = def->binding; - free_members(def->binding); - free(def->binding); + if (def->binding != NULL) { + free_members(def->binding); + free(def->binding); + } } rcstr_delref(def->file); free(def->var);