git: c04ad15ca7db - main - config: address a number of Coverity issues

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Thu, 16 Feb 2023 20:37:37 UTC
The branch main has been updated by kevans:

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

commit c04ad15ca7dbe9034b274e404edc0bcf6a5300e0
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2023-02-16 20:36:17 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2023-02-16 20:37:06 +0000

    config: address a number of Coverity issues
    
    Highlights:
    - Various memory leaks
    - FILE* leaks
    - `tsize` in moveifchanged() is only needed if !changed, and `from_sb`
        is only valid if !changed.
    - Simplify trivially true expression
    - Sanity check elfdump size output (+ fix variable sizes) (des@)
    
    CID:    1471167, 1006391, 1505333, 1505275, 1505349, 1505306, 1505232
    Reviewed by:    imp
    Differential Revision:  https://reviews.freebsd.org/D38643
---
 usr.sbin/config/lang.l       |  2 ++
 usr.sbin/config/main.cc      | 10 ++++++----
 usr.sbin/config/mkoptions.cc | 20 +++++++++++++++-----
 3 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/usr.sbin/config/lang.l b/usr.sbin/config/lang.l
index ed0b2aa794b3..243b66666d0e 100644
--- a/usr.sbin/config/lang.l
+++ b/usr.sbin/config/lang.l
@@ -297,6 +297,8 @@ include(const char *fname, int ateof)
 		return (-1);
 	}
 	cfgfile_add(fnamebuf == NULL ? fname : fnamebuf);
+	free(fnamebuf);
+
 	in = malloc(sizeof(*in));
 	assert(in != NULL);
 	in->in_prev = inclp;
diff --git a/usr.sbin/config/main.cc b/usr.sbin/config/main.cc
index 66a071401183..f6c99e32c594 100644
--- a/usr.sbin/config/main.cc
+++ b/usr.sbin/config/main.cc
@@ -616,9 +616,9 @@ moveifchanged(const char *from_name, const char *to_name)
 	if (!changed && from_sb.st_size != to_sb.st_size)
 		changed++;
 
-	tsize = (size_t)from_sb.st_size;
-
 	if (!changed) {
+		tsize = (size_t)from_sb.st_size;
+
 		p = (char *)mmap(NULL, tsize, PROT_READ, MAP_SHARED, from_fd,
 		    (off_t)0);
 		if (p == MAP_FAILED)
@@ -736,7 +736,7 @@ kernconfdump(const char *file)
 	struct stat st;
 	FILE *fp, *pp;
 	int error, osz, r;
-	unsigned int i, off, size, t1, t2, align;
+	size_t i, off, size, t1, t2, align;
 	char *cmd, *o;
 
 	r = open(file, O_RDONLY);
@@ -765,8 +765,10 @@ kernconfdump(const char *file)
 	free(cmd);
 	(void)fread(o, osz, 1, pp);
 	pclose(pp);
-	r = sscanf(o, "%d%d%d%d%d", &off, &size, &t1, &t2, &align);
+	r = sscanf(o, "%zu%zu%zu%zu%zu", &off, &size, &t1, &t2, &align);
 	free(o);
+	if (size > SIZE_MAX - off || off + size > (size_t)st.st_size)
+		errx(EXIT_FAILURE, "%s: incoherent ELF headers", file);
 	if (r != 5)
 		errx(EXIT_FAILURE, "File %s doesn't contain configuration "
 		    "file. Either unsupported, or not compiled with "
diff --git a/usr.sbin/config/mkoptions.cc b/usr.sbin/config/mkoptions.cc
index 134c09c2d074..1ffb9722af8b 100644
--- a/usr.sbin/config/mkoptions.cc
+++ b/usr.sbin/config/mkoptions.cc
@@ -263,7 +263,7 @@ do_option(char *name)
 		if (op == NULL)
 			err(EXIT_FAILURE, "calloc");
 		op->op_name = ns(name);
-		op->op_value = value ? ns(value) : NULL;
+		op->op_value = ns(value);
 		SLIST_INSERT_HEAD(&op_head, op, op_next);
 	}
 
@@ -383,8 +383,10 @@ read_option_file(const char *fname, int flags)
 		}
 		optname = ns(wd);
 		wd = get_word(fp);
-		if (wd.eof())
-			return (1);
+		if (wd.eof()) {
+			free(optname);
+			break;
+		}
 		if (wd.eol()) {
 			if (flags) {
 				fprintf(stderr, "%s: compat file requires two"
@@ -399,10 +401,18 @@ read_option_file(const char *fname, int flags)
 		} else {
 			val = ns(wd);
 		}
-		if (flags == 0)
+
+		if (flags == 0) {
+			/*
+			 * insert_option takes possession of `optname` in the
+			 * new option instead of making yet another copy.
+			 */
 			insert_option(fname, optname, val);
-		else
+		} else {
 			update_option(optname, val, flags);
+			free(optname);
+			optname = NULL;
+		}
 	}
 	(void)fclose(fp);
 	return (1);