git: 526bd072b33e - main - syslogd: Fix resource leaks

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Fri, 03 Jan 2025 01:53:17 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=526bd072b33e3e255748e547fdc21ab15e77b709

commit 526bd072b33e3e255748e547fdc21ab15e77b709
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-01-03 01:51:19 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-01-03 01:51:19 +0000

    syslogd: Fix resource leaks
    
    - nvlist_append_nvlist_array() makes a copy of the input nvlist, so the
      pattern of nvlist_append_nvlist_array(... cfline(...)) would leak
      memory and descriptors.  Pass the entire config nvlist to cfline()
      instead since this is needed for a future change.
    - In parse_action(), free the linked list returned by getaddrinfo().
    - Remove some checks at the beginning of close_filed().  For some log
      types we'll always have f->f_file == -1, in which case we wouldn't
      release other resources, such as forwarding sockets.
    - After converting a filed to an nvlist, free the filed resources.
    
    Fixes:  2567168dc498 ("syslogd: Refresh configuration using libcasper")
    Reviewed by:    jfree
    Differential Revision:  https://reviews.freebsd.org/D48250
---
 usr.sbin/syslogd/syslogd.c | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
index be4eaa235d36..e1d3dffe013a 100644
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -334,7 +334,8 @@ struct iovlist;
 static bool	allowaddr(char *);
 static void	addpeer(const char *, const char *, mode_t);
 static void	addsock(const char *, const char *, mode_t);
-static nvlist_t *cfline(const char *, const char *, const char *, const char *);
+static void	cfline(nvlist_t *, const char *, const char *, const char *,
+    const char *);
 static const char *cvthname(struct sockaddr *);
 static struct deadq_entry *deadq_enter(int);
 static void	deadq_remove(struct deadq_entry *);
@@ -369,10 +370,6 @@ static void	increase_rcvbuf(int);
 static void
 close_filed(struct filed *f)
 {
-
-	if (f == NULL || f->f_file == -1)
-		return;
-
 	switch (f->f_type) {
 	case F_FORW:
 		if (f->f_addr_fds != NULL) {
@@ -409,7 +406,8 @@ close_filed(struct filed *f)
 	default:
 		break;
 	}
-	(void)close(f->f_file);
+	if (f->f_file != -1)
+		(void)close(f->f_file);
 	f->f_file = -1;
 }
 
@@ -2447,8 +2445,7 @@ parseconfigfile(FILE *cf, bool allow_includes, nvlist_t *nvl_conf)
 		}
 		for (i = strlen(cline) - 1; i >= 0 && isspace(cline[i]); i--)
 			cline[i] = '\0';
-		nvlist_append_nvlist_array(nvl_conf, "filed_list",
-		    cfline(cline, prog, host, pfilter));
+		cfline(nvl_conf, cline, prog, host, pfilter);
 
 	}
 	return (nvl_conf);
@@ -2472,10 +2469,8 @@ readconfigfile(const char *path)
 		(void)fclose(cf);
 	} else {
 		dprintf("cannot open %s\n", path);
-		nvlist_append_nvlist_array(nvl_conf, "filed_list",
-		    cfline("*.ERR\t/dev/console", "*", "*", "*"));
-		nvlist_append_nvlist_array(nvl_conf, "filed_list",
-		    cfline("*.PANIC\t*", "*", "*", "*"));
+		cfline(nvl_conf, "*.ERR\t/dev/console", "*", "*", "*");
+		cfline(nvl_conf, "*.PANIC\t*", "*", "*", "*");
 	}
 	return (nvl_conf);
 }
@@ -3071,7 +3066,7 @@ parse_action(const char *p, struct filed *f)
 			if (shutdown(*sockp, SHUT_RD) < 0)
 				err(1, "shutdown");
 		}
-
+		freeaddrinfo(res);
 		f->f_type = F_FORW;
 		break;
 
@@ -3125,10 +3120,11 @@ parse_action(const char *p, struct filed *f)
 }
 
 /*
- * Crack a configuration file line
+ * Convert a configuration file line to an nvlist and add to "nvl", which
+ * contains all of the log configuration processed thus far.
  */
-static nvlist_t *
-cfline(const char *line, const char *prog, const char *host,
+static void
+cfline(nvlist_t *nvl, const char *line, const char *prog, const char *host,
     const char *pfilter)
 {
 	nvlist_t *nvl_filed;
@@ -3169,6 +3165,7 @@ cfline(const char *line, const char *prog, const char *host,
 
 	/* An nvlist is heap allocated heap here. */
 	nvl_filed = filed_to_nvlist(&f);
+	close_filed(&f);
 
 	if (pfilter && *pfilter != '*') {
 		nvlist_t *nvl_pfilter;
@@ -3179,7 +3176,8 @@ cfline(const char *line, const char *prog, const char *host,
 		nvlist_add_nvlist(nvl_filed, "f_prop_filter", nvl_pfilter);
 	}
 
-	return (nvl_filed);
+	nvlist_append_nvlist_array(nvl, "filed_list", nvl_filed);
+	nvlist_destroy(nvl_filed);
 }
 
 /*