From: Todd C. Miller Date: Sat, 28 Mar 2009 13:09:51 +0000 (+0000) Subject: Make alias_remove return the alias struct instead of freeing it directly. X-Git-Tag: SUDO_1_7_1~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7bf7af9414a50344168797a08d6883186364ff69;p=sudo Make alias_remove return the alias struct instead of freeing it directly. Fixes a use after free in alias_remove_recursive, the only consumer. --- diff --git a/alias.c b/alias.c index 8b8b29e06..4ceba8544 100644 --- 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 010f0b36f..38a572d88 100644 --- 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)); diff --git a/visudo.c b/visudo.c index a80ab2b25..a3d5ef8ca 100644 --- 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); }