]> granicus.if.org Git - sudo/commitdiff
Add free_default() to free a struct defaults pointer so we have a
authorTodd C. Miller <Todd.Miller@sudo.ws>
Wed, 21 Mar 2018 18:11:19 +0000 (12:11 -0600)
committerTodd C. Miller <Todd.Miller@sudo.ws>
Wed, 21 Mar 2018 18:11:19 +0000 (12:11 -0600)
single place where we free the defaults.  A pointer to the previous
Default's binding may be passed in to avoid freeing an already free
binding.

plugins/sudoers/defaults.c
plugins/sudoers/gram.c
plugins/sudoers/gram.y
plugins/sudoers/parse.h

index 69766a81d8916f2875633435b55878eb107ea05d..b6ba7fad5c1cc198a67351c304551573e9640197 100644 (file)
@@ -457,7 +457,7 @@ run_early_defaults(void)
 }
 
 static void
-free_default(int type, union sudo_defs_val *sd_un)
+free_defs_val(int type, union sudo_defs_val *sd_un)
 {
     switch (type & T_MASK) {
        case T_STR:
@@ -484,7 +484,7 @@ init_defaults(void)
     /* Clear any old settings. */
     if (!firsttime) {
        for (def = sudo_defs_table; def->name != NULL; def++)
-           free_default(def->type, &def->sd_un);
+           free_defs_val(def->type, &def->sd_un);
     }
 
     /* First initialize the flags. */
@@ -800,7 +800,7 @@ check_defaults(bool quiet)
            memset(&sd_un, 0, sizeof(sd_un));
            if (parse_default_entry(def, d->val, d->op, &sd_un, d->file,
                d->lineno, quiet)) {
-               free_default(def->type, &sd_un);
+               free_defs_val(def->type, &sd_un);
                continue;
            }
        }
index 2a7ddf2346b9f1daf7f00e04f34781a5f40eac40..ba58037458a940191083686746b75c074538837c 100644 (file)
@@ -837,6 +837,8 @@ add_userspec(struct member *members, struct privilege *privs)
 void
 free_member(struct member *m)
 {
+    debug_decl(free_member, SUDOERS_DEBUG_PARSER)
+
     if (m->type == COMMAND) {
            struct sudo_command *c = (struct sudo_command *)m->name;
            free(c->cmnd);
@@ -848,6 +850,8 @@ free_member(struct member *m)
     }
     free(m->name);
     free(m);
+
+    debug_return;
 }
 
 /*
@@ -857,17 +861,39 @@ void
 free_members(struct member_list *members)
 {
     struct member *m;
+    debug_decl(free_members, SUDOERS_DEBUG_PARSER)
 
     while ((m = TAILQ_FIRST(members)) != NULL) {
        TAILQ_REMOVE(members, m, entries);
        free_member(m);
     }
+
+    debug_return;
+}
+
+struct member_list *
+free_default(struct defaults *def, struct member_list *binding)
+{
+    debug_decl(free_default, SUDOERS_DEBUG_PARSER)
+
+    if (def->binding != binding) {
+       binding = def->binding;
+       free_members(def->binding);
+       free(def->binding);
+    }
+    rcstr_delref(def->file);
+    free(def->var);
+    free(def->val);
+    free(def);
+
+    debug_return_ptr(binding);
 }
 
 void
 free_privilege(struct privilege *priv)
 {
     struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
+    struct member_list *binding = NULL;
     struct cmndspec *cs;
     struct defaults *def;
 #ifdef HAVE_SELINUX
@@ -876,6 +902,7 @@ free_privilege(struct privilege *priv)
 #ifdef HAVE_PRIV_SET
     char *privs = NULL, *limitprivs = NULL;
 #endif /* HAVE_PRIV_SET */
+    debug_decl(free_privilege, SUDOERS_DEBUG_PARSER)
 
     free(priv->ldap_role);
     free_members(&priv->hostlist);
@@ -919,11 +946,11 @@ free_privilege(struct privilege *priv)
     }
     while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) {
        TAILQ_REMOVE(&priv->defaults, def, entries);
-       free(def->var);
-       free(def->val);
-       free(def);
+       binding = free_default(def, binding);
     }
     free(priv);
+
+    debug_return;
 }
 
 void
@@ -931,6 +958,7 @@ free_userspec(struct userspec *us)
 {
     struct privilege *priv;
     struct sudoers_comment *comment;
+    debug_decl(free_userspec, SUDOERS_DEBUG_PARSER)
 
     free_members(&us->users);
     while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
@@ -944,6 +972,8 @@ free_userspec(struct userspec *us)
     }
     rcstr_delref(us->file);
     free(us);
+
+    debug_return;
 }
 
 /*
@@ -953,8 +983,8 @@ free_userspec(struct userspec *us)
 bool
 init_parser(const char *path, bool quiet)
 {
-    struct member_list *binding;
-    struct defaults *d;
+    struct member_list *binding = NULL;
+    struct defaults *def;
     struct userspec *us;
     bool ret = true;
     void *next;
@@ -965,17 +995,8 @@ init_parser(const char *path, bool quiet)
     }
     TAILQ_INIT(&userspecs);
 
-    binding = NULL;
-    TAILQ_FOREACH_SAFE(d, &defaults, entries, next) {
-       if (d->binding != binding) {
-           binding = d->binding;
-           free_members(d->binding);
-           free(d->binding);
-       }
-       rcstr_delref(d->file);
-       free(d->var);
-       free(d->val);
-       free(d);
+    TAILQ_FOREACH_SAFE(def, &defaults, entries, next) {
+       binding = free_default(def, binding);
     }
     TAILQ_INIT(&defaults);
 
@@ -1023,7 +1044,7 @@ init_options(struct command_options *opts)
     opts->limitprivs = NULL;
 #endif
 }
-#line 974 "gram.c"
+#line 995 "gram.c"
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
 #if defined(__cplusplus) || defined(__STDC__)
 static int yygrowstack(void)
@@ -2148,7 +2169,7 @@ case 116:
                            }
                        }
 break;
-#line 2099 "gram.c"
+#line 2120 "gram.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
index 1f36c50571f0b6a7b9d5aa25d5a341e7ffceb3a3..59f40b25eed64571cc3fdd1f36da1bc669839952 100644 (file)
@@ -1065,6 +1065,8 @@ add_userspec(struct member *members, struct privilege *privs)
 void
 free_member(struct member *m)
 {
+    debug_decl(free_member, SUDOERS_DEBUG_PARSER)
+
     if (m->type == COMMAND) {
            struct sudo_command *c = (struct sudo_command *)m->name;
            free(c->cmnd);
@@ -1076,6 +1078,8 @@ free_member(struct member *m)
     }
     free(m->name);
     free(m);
+
+    debug_return;
 }
 
 /*
@@ -1085,17 +1089,39 @@ void
 free_members(struct member_list *members)
 {
     struct member *m;
+    debug_decl(free_members, SUDOERS_DEBUG_PARSER)
 
     while ((m = TAILQ_FIRST(members)) != NULL) {
        TAILQ_REMOVE(members, m, entries);
        free_member(m);
     }
+
+    debug_return;
+}
+
+struct member_list *
+free_default(struct defaults *def, struct member_list *binding)
+{
+    debug_decl(free_default, SUDOERS_DEBUG_PARSER)
+
+    if (def->binding != binding) {
+       binding = def->binding;
+       free_members(def->binding);
+       free(def->binding);
+    }
+    rcstr_delref(def->file);
+    free(def->var);
+    free(def->val);
+    free(def);
+
+    debug_return_ptr(binding);
 }
 
 void
 free_privilege(struct privilege *priv)
 {
     struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
+    struct member_list *binding = NULL;
     struct cmndspec *cs;
     struct defaults *def;
 #ifdef HAVE_SELINUX
@@ -1104,6 +1130,7 @@ free_privilege(struct privilege *priv)
 #ifdef HAVE_PRIV_SET
     char *privs = NULL, *limitprivs = NULL;
 #endif /* HAVE_PRIV_SET */
+    debug_decl(free_privilege, SUDOERS_DEBUG_PARSER)
 
     free(priv->ldap_role);
     free_members(&priv->hostlist);
@@ -1147,11 +1174,11 @@ free_privilege(struct privilege *priv)
     }
     while ((def = TAILQ_FIRST(&priv->defaults)) != NULL) {
        TAILQ_REMOVE(&priv->defaults, def, entries);
-       free(def->var);
-       free(def->val);
-       free(def);
+       binding = free_default(def, binding);
     }
     free(priv);
+
+    debug_return;
 }
 
 void
@@ -1159,6 +1186,7 @@ free_userspec(struct userspec *us)
 {
     struct privilege *priv;
     struct sudoers_comment *comment;
+    debug_decl(free_userspec, SUDOERS_DEBUG_PARSER)
 
     free_members(&us->users);
     while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
@@ -1172,6 +1200,8 @@ free_userspec(struct userspec *us)
     }
     rcstr_delref(us->file);
     free(us);
+
+    debug_return;
 }
 
 /*
@@ -1181,8 +1211,8 @@ free_userspec(struct userspec *us)
 bool
 init_parser(const char *path, bool quiet)
 {
-    struct member_list *binding;
-    struct defaults *d;
+    struct member_list *binding = NULL;
+    struct defaults *def;
     struct userspec *us;
     bool ret = true;
     void *next;
@@ -1193,17 +1223,8 @@ init_parser(const char *path, bool quiet)
     }
     TAILQ_INIT(&userspecs);
 
-    binding = NULL;
-    TAILQ_FOREACH_SAFE(d, &defaults, entries, next) {
-       if (d->binding != binding) {
-           binding = d->binding;
-           free_members(d->binding);
-           free(d->binding);
-       }
-       rcstr_delref(d->file);
-       free(d->var);
-       free(d->val);
-       free(d);
+    TAILQ_FOREACH_SAFE(def, &defaults, entries, next) {
+       binding = free_default(def, binding);
     }
     TAILQ_INIT(&defaults);
 
index 85c9e750bc0886d74b96b0760c743fdc1741c569..347baa77cdd208d24cf6fc91e18f94f8ccc32c05 100644 (file)
@@ -268,6 +268,7 @@ void free_member(struct member *m);
 void free_members(struct member_list *members);
 void free_privilege(struct privilege *priv);
 void free_userspec(struct userspec *us);
+struct member_list *free_default(struct defaults *def, struct member_list *binding);
 
 /* match_addr.c */
 bool addr_matches(char *n);