[SeaBIOS] unbounded-writes, causes buffer overflow

Datta manikanta sri hari Danduri posted 1 patch 10 months, 2 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/seabios tags/patchew/DM5PR2201MB17376672DC958FE5B56CDA6CA6BFA@DM5PR2201MB1737.namprd22.prod.outlook.com
[SeaBIOS] unbounded-writes, causes buffer overflow
Posted by Datta manikanta sri hari Danduri 10 months, 2 weeks ago
Hi

There are a few bugs related to Buffer write operations that do not control the length of data, which may overflow. I attached a reference patch. Please make changes as needed.
If possible, assign CVE, as the content written to these buffers is tainted and coming from the user, which can lead to security risks.

Thanks
Srihari
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 08e7559..ed96045 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -110,7 +110,9 @@ char *conf_get_default_confname(void)
 	name = conf_expand_value(conf_defname);
 	env = getenv(SRCTREE);
 	if (env) {
-		sprintf(fullname, "%s/%s", env, name);
+		int fullname_max_bytes = snprintf(fullname, sizeof(fullname), "%s/%s", env, name);
+		if ((fullname_max_bytes < 0) || (fullname_max_bytes >= sizeof(fullname)))
+			return NULL;
 		if (!stat(fullname, &buf))
 			return fullname;
 	}
@@ -768,10 +770,14 @@ int conf_write(const char *name)
 	} else
 		basename = conf_get_configname();
 
-	sprintf(newname, "%s%s", dirname, basename);
+	int newname_max_bytes = snprintf(newname, sizeof(newname), "%s%s",dirname, basename);
+	if ((newname_max_bytes < 0) || (newname_max_bytes >= sizeof(newname)))
+		return 1;
 	env = getenv("KCONFIG_OVERWRITECONFIG");
 	if (!env || !*env) {
-		sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
+		int tmpname_max_bytes = snprintf(tmpname, sizeof(tmpname), "%s.tmpconfig.%d", dirname, (int)getpid());
+		if ((tmpname_max_bytes < 0) || (tmpname_max_bytes >= sizeof(tmpname)))
+			return 1;
 		out = fopen(tmpname, "w");
 	} else {
 		*tmpname = 0;
@@ -822,6 +828,8 @@ next:
 	fclose(out);
 
 	if (*tmpname) {
+		if (strlen(dirname) + strlen(basename) + 5 > sizeof(dirname))
+			return 1;
 		strcat(dirname, basename);
 		strcat(dirname, ".old");
 		rename(newname, dirname);
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 7caabdb..2d6407a 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -675,7 +675,10 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
 		sym->def[S_DEF_USER].val = val = xmalloc(size);
 	else
 		return true;
-
+	if((strlen(val) + strlen(newval) + 1) > size) {
+		size = strlen(val) + strlen(newval) + 1;
+		sym->def[S_DEF_USER].val = val = realloc(val, size);
+	}
 	strcpy(val, newval);
 	free((void *)oldval);
 	sym_clear_all_valid();
@@ -907,6 +910,10 @@ const char *sym_expand_string_value(const char *in)
 		strcat(res, symval);
 		in = src;
 	}
+	if((strlen(res) + strlen(in) + 1) > reslen) {
+		reslen = strlen(res) + strlen(in) + 1;
+		res = realloc(res, reslen);
+	}
 	strcat(res, in);
 
 	return res;
diff --git a/scripts/kconfig/zconf.lex.c_shipped b/scripts/kconfig/zconf.lex.c_shipped
index 349a7f2..cccfb29 100644
--- a/scripts/kconfig/zconf.lex.c_shipped
+++ b/scripts/kconfig/zconf.lex.c_shipped
@@ -2328,7 +2328,9 @@ FILE *zconf_fopen(const char *name)
 	if (!f && name != NULL && name[0] != '/') {
 		env = getenv(SRCTREE);
 		if (env) {
-			sprintf(fullname, "%s/%s", env, name);
+			int fname_max_bytes = snprintf(fullname, sizeof(fullname), "%s/%s", env, name);
+			if((fname_max_bytes < 0) || (fname_max_bytes >= sizeof(fullname)))
+				return NULL;
 			f = fopen(fullname, "r");
 		}
 	}
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-leave@seabios.org