From: Willy Tarreau Date: Mon, 11 May 2026 13:06:41 +0000 (+0200) Subject: BUG/MINOR: auth: free user groups on error paths in userlist_postinit() X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=fdfecc55899e801558c9cad00761608a03497278;p=haproxy.git BUG/MINOR: auth: free user groups on error paths in userlist_postinit() In userlist_postinit(), when an error occurs (missing group, missing user, or allocation failure), the function returned immediately without freeing the auth_groups_list linked lists that were built for all users in the first loop. Each user's curuser->u.groups pointed to these allocated nodes, which leaked on every error path. Fix by replacing direct returns with a goto to a centralized cleanup label that frees all users' groups lists before returning the error. Also fix a trailing double space in one error return statement while refactoring. Note that the impact is very low since we're supposed to fail to boo after such errors. --- diff --git a/src/auth.c b/src/auth.c index 92f5bc2ba..f2380753a 100644 --- a/src/auth.c +++ b/src/auth.c @@ -129,7 +129,7 @@ int userlist_postinit() for (curuserlist = userlist; curuserlist; curuserlist = curuserlist->next) { struct auth_groups *ag; struct auth_users *curuser; - struct auth_groups_list *grl; + struct auth_groups_list *grl, *tmp; for (curuser = curuserlist->users; curuser; curuser = curuser->next) { char *group = NULL; @@ -152,7 +152,7 @@ int userlist_postinit() groups = groups->next; free(grl); } - return ERR_ALERT | ERR_FATAL; + goto free_groups; } /* Add this group at the group userlist. */ @@ -165,7 +165,7 @@ int userlist_postinit() groups = groups->next; free(grl); } - return ERR_ALERT | ERR_FATAL; + goto free_groups; } grl->group = ag; @@ -192,7 +192,7 @@ int userlist_postinit() if (!curuser) { ha_alert("userlist '%s': no such user '%s' specified in group '%s'\n", curuserlist->name, user, ag->name); - return ERR_ALERT | ERR_FATAL; + goto free_groups; } /* Add this group at the group userlist. */ @@ -200,7 +200,7 @@ int userlist_postinit() if (!grl) { ha_alert("userlist '%s': no more memory when trying to allocate the user groups.\n", curuserlist->name); - return ERR_ALERT | ERR_FATAL; + goto free_groups; } grl->group = ag; @@ -211,6 +211,22 @@ int userlist_postinit() ha_free(&ag->groupusers); } + goto next_userlist; + + free_groups: + /* Free already-assigned groups for all users in this userlist. */ + for (curuser = curuserlist->users; curuser; curuser = curuser->next) { + grl = curuser->u.groups; + while (grl) { + tmp = grl; + grl = grl->next; + free(tmp); + } + curuser->u.groups = NULL; + } + return ERR_ALERT | ERR_FATAL; + + next_userlist:; #ifdef DEBUG_AUTH for (ag = curuserlist->groups; ag; ag = ag->next) { struct auth_groups_list *agl;