From e36fb1b3c0bc60ebb5104525565f1e9b7326b33f Mon Sep 17 00:00:00 2001 From: djm Date: Mon, 4 Mar 2024 04:13:18 +0000 Subject: [PATCH] fix leak of CanonicalizePermittedCNAMEs on error path; spotted by Coverity (CID 438039) --- usr.bin/ssh/readconf.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index 71ef9056c66..101d878d540 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.385 2024/03/04 02:16:11 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.386 2024/03/04 04:13:18 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -867,6 +867,20 @@ parse_token(const char *cp, const char *filename, int linenum, return oBadOption; } +static void +free_canon_cnames(struct allowed_cname *cnames, u_int n) +{ + u_int i; + + if (cnames == NULL || n == 0) + return; + for (i = 0; i < n; i++) { + free(cnames[i].source_list); + free(cnames[i].target_list); + } + free(cnames); +} + /* Multistate option parsing */ struct multistate { char *key; @@ -2137,13 +2151,10 @@ parse_pubkey_algos: if (found && *activep) { options->permitted_cnames = cnames; options->num_permitted_cnames = ncnames; - } else { - for (i = 0; i < ncnames; i++) { - free(cnames[i].source_list); - free(cnames[i].target_list); - } - free(cnames); + cnames = NULL; /* transferred */ + ncnames = 0; } + /* un-transferred cnames is cleaned up before exit */ break; case oCanonicalizeHostname: @@ -2382,6 +2393,7 @@ parse_pubkey_algos: /* success */ ret = 0; out: + free_canon_cnames(cnames, ncnames); opt_array_free2(strs, NULL, nstrs); argv_free(oav, oac); return ret; -- 2.20.1