]> granicus.if.org Git - sudo/commitdiff
Make alias_remove return the alias struct instead of freeing it directly.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 28 Mar 2009 13:09:51 +0000 (13:09 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 28 Mar 2009 13:09:51 +0000 (13:09 +0000)
Fixes a use after free in alias_remove_recursive, the only consumer.

alias.c
parse.h
visudo.c

diff --git a/alias.c b/alias.c
index 8b8b29e0623def8a283db384f46235514aef57f9..4ceba8544904cbbd4dd2c26dc3037815bf3e308f 100644 (file)
--- a/alias.c
+++ b/alias.c
@@ -60,7 +60,6 @@ unsigned int alias_seqno;
  * Local protoypes
  */
 static int   alias_compare     __P((const void *, const void *));
-static void  alias_free                __P((void *));
 
 /*
  * Comparison function for the red-black tree.
@@ -161,7 +160,7 @@ no_aliases()
 /*
  * Free memory used by an alias struct and its members.
  */
-static void
+void
 alias_free(v)
     void *v;
 {
@@ -185,9 +184,9 @@ alias_free(v)
 }
 
 /*
- * Find the named alias, delete it from the tree and recover its resources.
+ * Find the named alias, remove it from the tree and return it.
  */
-int
+struct alias *
 alias_remove(name, type)
     char *name;
     int type;
@@ -198,10 +197,9 @@ alias_remove(name, type)
     key.name = name;
     key.type = type;
     if ((node = rbfind(aliases, &key)) == NULL)
-       return(FALSE);
+       return(NULL);
     a = rbdelete(aliases, node);
-    alias_free(a);
-    return(TRUE);
+    return(a);
 }
 
 void
diff --git a/parse.h b/parse.h
index 010f0b36f543db7763e2a263ec049f1217d612c8..38a572d88710743a75406c9b0daa9bad3548bfde 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -168,7 +168,6 @@ extern unsigned int alias_seqno;
  */
 char *alias_add                __P((char *, int, struct member *));
 int addr_matches       __P((char *));
-int alias_remove       __P((char *, int));
 int cmnd_matches       __P((struct member *));
 int cmndlist_matches   __P((struct member_list *));
 int command_matches    __P((char *, char *));
@@ -182,6 +181,8 @@ int usergr_matches  __P((char *, char *, struct passwd *));
 int userpw_matches     __P((char *, char *, struct passwd *));
 int group_matches      __P((char *, struct group *));
 struct alias *alias_find __P((char *, int));
+struct alias *alias_remove __P((char *, int));
+void alias_free                __P((void *));
 void alias_apply       __P((int (*)(void *, void *), void *));
 void init_aliases      __P((void));
 void init_parser       __P((char *, int));
index a80ab2b25be70aa5786692ac879146d2e1224604..a3d5ef8ca20086df2605fe08cd3c7b1869426bb3 100644 (file)
--- a/visudo.c
+++ b/visudo.c
@@ -942,7 +942,6 @@ alias_remove_recursive(name, type)
     struct member *m;
     struct alias *a;
 
-    alias_seqno++;
     if ((a = alias_find(name, type)) != NULL) {
        tq_foreach_fwd(&a->members, m) {
            if (m->type == ALIAS) {
@@ -950,6 +949,7 @@ alias_remove_recursive(name, type)
            }
        }
     }
+    alias_seqno++;
     (void) alias_remove(name, type);
 }