Refactor member freeing code into free_member().

Refactor userspec freeing code into free_userspec().
This commit is contained in:
Todd C. Miller
2018-02-05 13:33:29 -07:00
parent 9d49592f14
commit 5cca4b6906
3 changed files with 182 additions and 190 deletions

View File

@@ -830,49 +830,46 @@ add_userspec(struct member *members, struct privilege *privs)
debug_return_bool(true); debug_return_bool(true);
} }
/*
* Free a member struct and its contents.
*/
void
free_member(struct member *m)
{
if (m->type == COMMAND) {
struct sudo_command *c = (struct sudo_command *)m->name;
free(c->cmnd);
free(c->args);
if (c->digest != NULL) {
free(c->digest->digest_str);
free(c->digest);
}
}
free(m->name);
free(m);
}
/* /*
* Free a tailq of members but not the struct member_list container itself. * Free a tailq of members but not the struct member_list container itself.
*/ */
void void
free_members(struct member_list *members) free_members(struct member_list *members)
{ {
struct member *m, *next; struct member *m;
struct sudo_command *c;
TAILQ_FOREACH_SAFE(m, members, entries, next) { while ((m = TAILQ_FIRST(members)) != NULL) {
if (m->type == COMMAND) { TAILQ_REMOVE(members, m, entries);
c = (struct sudo_command *) m->name; free_member(m);
free(c->cmnd);
free(c->args);
}
free(m->name);
free(m);
} }
} }
/* void
* Free up space used by data structures from a previous parser run and sets free_userspec(struct userspec *us)
* the current sudoers file to path.
*/
bool
init_parser(const char *path, bool quiet)
{ {
struct member_list *binding; struct privilege *priv, *next;
struct defaults *d, *d_next;
struct userspec *us, *us_next;
bool ret = true;
debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
/* XXX - move into a free function */ free_members(&us->users);
TAILQ_FOREACH_SAFE(us, &userspecs, entries, us_next) { TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, next) {
struct member *m, *m_next;
struct privilege *priv, *priv_next;
TAILQ_FOREACH_SAFE(m, &us->users, entries, m_next) {
free(m->name);
free(m);
}
TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, priv_next) {
struct member_list *runasuserlist = NULL, *runasgrouplist = NULL; struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
struct cmndspec *cs, *cs_next; struct cmndspec *cs, *cs_next;
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
@@ -882,10 +879,7 @@ init_parser(const char *path, bool quiet)
char *privs = NULL, *limitprivs = NULL; char *privs = NULL, *limitprivs = NULL;
#endif /* HAVE_PRIV_SET */ #endif /* HAVE_PRIV_SET */
TAILQ_FOREACH_SAFE(m, &priv->hostlist, entries, m_next) { free_members(&priv->hostlist);
free(m->name);
free(m);
}
TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, cs_next) { TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, cs_next) {
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
/* Only free the first instance of a role/type. */ /* Only free the first instance of a role/type. */
@@ -912,32 +906,15 @@ init_parser(const char *path, bool quiet)
/* Only free the first instance of runas user/group lists. */ /* Only free the first instance of runas user/group lists. */
if (cs->runasuserlist && cs->runasuserlist != runasuserlist) { if (cs->runasuserlist && cs->runasuserlist != runasuserlist) {
runasuserlist = cs->runasuserlist; runasuserlist = cs->runasuserlist;
TAILQ_FOREACH_SAFE(m, runasuserlist, entries, m_next) { free_members(runasuserlist);
free(m->name);
free(m);
}
free(runasuserlist); free(runasuserlist);
} }
if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) { if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) {
runasgrouplist = cs->runasgrouplist; runasgrouplist = cs->runasgrouplist;
TAILQ_FOREACH_SAFE(m, runasgrouplist, entries, m_next) { free_members(runasgrouplist);
free(m->name);
free(m);
}
free(runasgrouplist); free(runasgrouplist);
} }
if (cs->cmnd->type == COMMAND) { free_member(cs->cmnd);
struct sudo_command *c =
(struct sudo_command *) cs->cmnd->name;
free(c->cmnd);
free(c->args);
if (c->digest != NULL) {
free(c->digest->digest_str);
free(c->digest);
}
}
free(cs->cmnd->name);
free(cs->cmnd);
free(cs); free(cs);
} }
free(priv); free(priv);
@@ -945,10 +922,28 @@ init_parser(const char *path, bool quiet)
rcstr_delref(us->file); rcstr_delref(us->file);
free(us); free(us);
} }
/*
* Free up space used by data structures from a previous parser run and sets
* the current sudoers file to path.
*/
bool
init_parser(const char *path, bool quiet)
{
struct member_list *binding;
struct defaults *d;
struct userspec *us;
bool ret = true;
void *next;
debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
TAILQ_FOREACH_SAFE(us, &userspecs, entries, next) {
free_userspec(us);
}
TAILQ_INIT(&userspecs); TAILQ_INIT(&userspecs);
binding = NULL; binding = NULL;
TAILQ_FOREACH_SAFE(d, &defaults, entries, d_next) { TAILQ_FOREACH_SAFE(d, &defaults, entries, next) {
if (d->binding != binding) { if (d->binding != binding) {
binding = d->binding; binding = d->binding;
free_members(d->binding); free_members(d->binding);
@@ -1005,7 +1000,7 @@ init_options(struct command_options *opts)
opts->limitprivs = NULL; opts->limitprivs = NULL;
#endif #endif
} }
#line 956 "gram.c" #line 951 "gram.c"
/* allocate initial stack or double stack size, up to YYMAXDEPTH */ /* allocate initial stack or double stack size, up to YYMAXDEPTH */
#if defined(__cplusplus) || defined(__STDC__) #if defined(__cplusplus) || defined(__STDC__)
static int yygrowstack(void) static int yygrowstack(void)
@@ -2129,7 +2124,7 @@ case 116:
} }
} }
break; break;
#line 2080 "gram.c" #line 2075 "gram.c"
} }
yyssp -= yym; yyssp -= yym;
yystate = *yyssp; yystate = *yyssp;

View File

@@ -1057,49 +1057,46 @@ add_userspec(struct member *members, struct privilege *privs)
debug_return_bool(true); debug_return_bool(true);
} }
/*
* Free a member struct and its contents.
*/
void
free_member(struct member *m)
{
if (m->type == COMMAND) {
struct sudo_command *c = (struct sudo_command *)m->name;
free(c->cmnd);
free(c->args);
if (c->digest != NULL) {
free(c->digest->digest_str);
free(c->digest);
}
}
free(m->name);
free(m);
}
/* /*
* Free a tailq of members but not the struct member_list container itself. * Free a tailq of members but not the struct member_list container itself.
*/ */
void void
free_members(struct member_list *members) free_members(struct member_list *members)
{ {
struct member *m, *next; struct member *m;
struct sudo_command *c;
TAILQ_FOREACH_SAFE(m, members, entries, next) { while ((m = TAILQ_FIRST(members)) != NULL) {
if (m->type == COMMAND) { TAILQ_REMOVE(members, m, entries);
c = (struct sudo_command *) m->name; free_member(m);
free(c->cmnd);
free(c->args);
}
free(m->name);
free(m);
} }
} }
/* void
* Free up space used by data structures from a previous parser run and sets free_userspec(struct userspec *us)
* the current sudoers file to path.
*/
bool
init_parser(const char *path, bool quiet)
{ {
struct member_list *binding; struct privilege *priv, *next;
struct defaults *d, *d_next;
struct userspec *us, *us_next;
bool ret = true;
debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
/* XXX - move into a free function */ free_members(&us->users);
TAILQ_FOREACH_SAFE(us, &userspecs, entries, us_next) { TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, next) {
struct member *m, *m_next;
struct privilege *priv, *priv_next;
TAILQ_FOREACH_SAFE(m, &us->users, entries, m_next) {
free(m->name);
free(m);
}
TAILQ_FOREACH_SAFE(priv, &us->privileges, entries, priv_next) {
struct member_list *runasuserlist = NULL, *runasgrouplist = NULL; struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
struct cmndspec *cs, *cs_next; struct cmndspec *cs, *cs_next;
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
@@ -1109,10 +1106,7 @@ init_parser(const char *path, bool quiet)
char *privs = NULL, *limitprivs = NULL; char *privs = NULL, *limitprivs = NULL;
#endif /* HAVE_PRIV_SET */ #endif /* HAVE_PRIV_SET */
TAILQ_FOREACH_SAFE(m, &priv->hostlist, entries, m_next) { free_members(&priv->hostlist);
free(m->name);
free(m);
}
TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, cs_next) { TAILQ_FOREACH_SAFE(cs, &priv->cmndlist, entries, cs_next) {
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
/* Only free the first instance of a role/type. */ /* Only free the first instance of a role/type. */
@@ -1139,32 +1133,15 @@ init_parser(const char *path, bool quiet)
/* Only free the first instance of runas user/group lists. */ /* Only free the first instance of runas user/group lists. */
if (cs->runasuserlist && cs->runasuserlist != runasuserlist) { if (cs->runasuserlist && cs->runasuserlist != runasuserlist) {
runasuserlist = cs->runasuserlist; runasuserlist = cs->runasuserlist;
TAILQ_FOREACH_SAFE(m, runasuserlist, entries, m_next) { free_members(runasuserlist);
free(m->name);
free(m);
}
free(runasuserlist); free(runasuserlist);
} }
if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) { if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) {
runasgrouplist = cs->runasgrouplist; runasgrouplist = cs->runasgrouplist;
TAILQ_FOREACH_SAFE(m, runasgrouplist, entries, m_next) { free_members(runasgrouplist);
free(m->name);
free(m);
}
free(runasgrouplist); free(runasgrouplist);
} }
if (cs->cmnd->type == COMMAND) { free_member(cs->cmnd);
struct sudo_command *c =
(struct sudo_command *) cs->cmnd->name;
free(c->cmnd);
free(c->args);
if (c->digest != NULL) {
free(c->digest->digest_str);
free(c->digest);
}
}
free(cs->cmnd->name);
free(cs->cmnd);
free(cs); free(cs);
} }
free(priv); free(priv);
@@ -1172,10 +1149,28 @@ init_parser(const char *path, bool quiet)
rcstr_delref(us->file); rcstr_delref(us->file);
free(us); free(us);
} }
/*
* Free up space used by data structures from a previous parser run and sets
* the current sudoers file to path.
*/
bool
init_parser(const char *path, bool quiet)
{
struct member_list *binding;
struct defaults *d;
struct userspec *us;
bool ret = true;
void *next;
debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
TAILQ_FOREACH_SAFE(us, &userspecs, entries, next) {
free_userspec(us);
}
TAILQ_INIT(&userspecs); TAILQ_INIT(&userspecs);
binding = NULL; binding = NULL;
TAILQ_FOREACH_SAFE(d, &defaults, entries, d_next) { TAILQ_FOREACH_SAFE(d, &defaults, entries, next) {
if (d->binding != binding) { if (d->binding != binding) {
binding = d->binding; binding = d->binding;
free_members(d->binding); free_members(d->binding);

View File

@@ -255,7 +255,9 @@ bool init_aliases(void);
/* gram.c */ /* gram.c */
bool init_parser(const char *path, bool quiet); bool init_parser(const char *path, bool quiet);
void free_member(struct member *m);
void free_members(struct member_list *members); void free_members(struct member_list *members);
void free_userspec(struct userspec *us);
/* match_addr.c */ /* match_addr.c */
bool addr_matches(char *n); bool addr_matches(char *n);