From 43436be7c1cc776f75353b9a5bcd338044d69e56 Mon Sep 17 00:00:00 2001 From: yasuoka Date: Wed, 10 Jul 2024 16:30:43 +0000 Subject: [PATCH] Fix memory leaks, a use after free, accessing outside the region introduced by recent commits. Found by malloc(3). --- usr.sbin/radiusd/parse.y | 5 ++--- usr.sbin/radiusd/radiusd.c | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/usr.sbin/radiusd/parse.y b/usr.sbin/radiusd/parse.y index 435482ca112..c43cd506d3a 100644 --- a/usr.sbin/radiusd/parse.y +++ b/usr.sbin/radiusd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.21 2024/07/09 17:26:14 yasuoka Exp $ */ +/* $OpenBSD: parse.y,v 1.22 2024/07/10 16:30:43 yasuoka Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -394,7 +394,6 @@ authenticate : AUTHENTICATE str_l BY STRING optdeco { yyerror("Out of memory: %s", strerror(errno)); goto authenticate_error; } - modref = create_module_ref($4); if ((auth->auth = create_module_ref($4)) == NULL) goto authenticate_error; auth->username = $2.v; @@ -495,7 +494,7 @@ account : ACCOUNT optquick str_l TO STRING optdeco { struct radiusd_module_ref *modref, *modreft; if ((acct = calloc(1, - sizeof(struct radiusd_authentication))) == NULL) { + sizeof(struct radiusd_accounting))) == NULL) { yyerror("Out of memory: %s", strerror(errno)); goto account_error; } diff --git a/usr.sbin/radiusd/radiusd.c b/usr.sbin/radiusd/radiusd.c index ec1cf51faa5..6825f897809 100644 --- a/usr.sbin/radiusd/radiusd.c +++ b/usr.sbin/radiusd/radiusd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radiusd.c,v 1.45 2024/07/09 17:26:14 yasuoka Exp $ */ +/* $OpenBSD: radiusd.c,v 1.46 2024/07/10 16:30:43 yasuoka Exp $ */ /* * Copyright (c) 2013, 2023 Internet Initiative Japan Inc. @@ -118,7 +118,7 @@ main(int argc, char *argv[]) { extern char *__progname; const char *conffile = CONFFILE; - int ch; + int ch, error; struct radiusd *radiusd; bool noaction = false; struct passwd *pw; @@ -213,10 +213,11 @@ main(int argc, char *argv[]) event_loop(0); + error = radiusd->error; radiusd_free(radiusd); event_base_free(NULL); - if (radiusd->error != 0) + if (error != 0) exit(EXIT_FAILURE); else exit(EXIT_SUCCESS); @@ -339,6 +340,7 @@ radiusd_free(struct radiusd *radiusd) struct radiusd_module *module, *modulet; struct radiusd_module_ref *modref, *modreft; struct radiusd_authentication *authen, *authent; + struct radiusd_accounting *acct, *acctt; TAILQ_FOREACH_SAFE(authen, &radiusd->authen, next, authent) { TAILQ_REMOVE(&radiusd->authen, authen, next); @@ -352,6 +354,19 @@ radiusd_free(struct radiusd *radiusd) free(authen->username); free(authen); } + TAILQ_FOREACH_SAFE(acct, &radiusd->account, next, acctt) { + TAILQ_REMOVE(&radiusd->account, acct, next); + free(acct->secret); + free(acct->acct); + TAILQ_FOREACH_SAFE(modref, &acct->deco, next, modreft) { + TAILQ_REMOVE(&acct->deco, modref, next); + free(modref); + } + for (i = 0; acct->username[i] != NULL; i++) + free(acct->username[i]); + free(acct->username); + free(acct); + } TAILQ_FOREACH_SAFE(module, &radiusd->module, next, modulet) { TAILQ_REMOVE(&radiusd->module, module, next); radiusd_module_unload(module); -- 2.20.1