Fix memory leaks, a use after free, accessing outside the region
authoryasuoka <yasuoka@openbsd.org>
Wed, 10 Jul 2024 16:30:43 +0000 (16:30 +0000)
committeryasuoka <yasuoka@openbsd.org>
Wed, 10 Jul 2024 16:30:43 +0000 (16:30 +0000)
introduced by recent commits.  Found by malloc(3).

usr.sbin/radiusd/parse.y
usr.sbin/radiusd/radiusd.c

index 435482c..c43cd50 100644 (file)
@@ -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 <henning@openbsd.org>
@@ -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;
                        }
index ec1cf51..6825f89 100644 (file)
@@ -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);