shithub: scc

Download patch

ref: 69dcb84e15e76e302abc2e68c7d56364885c9944
parent: 06ecbf0a8c425cef03cbd67cb818155738d759e0
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Nov 24 15:14:27 EST 2017

[nm] Add more overflow tests to nm()

--- a/nm/main.c
+++ b/nm/main.c
@@ -55,12 +55,15 @@
 {
 	struct myrohdr hdr;
 	struct myrosym *syms;
-	size_t n, siz;
+	size_t n, i;
+	long off;
 
 	if (rdmyrohdr(fp, &hdr) < 0) {
 		fprintf(stderr, "nm: %s: incorrect header\n", member);
 		return;
 	}
+	if ((off = ftell(fp)) < 0)
+		return;
 
 	if (hdr.symsize / MYROSYM_SIZ > SIZE_MAX)
 		goto too_big;
@@ -73,13 +76,28 @@
 
 	if (n > SIZE_MAX / sizeof(struct myrosym))
 		goto too_big;
+	if (off > LONG_MAX - hdr.strsize)
+		goto offset_overflow;
+	off += hdr.strsize;
+	if (off > LONG_MAX - hdr.secsize)
+		goto offset_overflow;
+	off += hdr.secsize;
 
-	siz = n * sizeof(struct myrosym);
-	syms = xmalloc(n);
+	if (fseek(fp, off, SEEK_SET) < 0)
+		return;
 
-	while (n--)
-		;
+	syms = xmalloc(n * sizeof(struct myrosym));
+	for (i = 0; n--; ++i) {
+		if (rdmyrosym(fp, &syms[i]) < 0)
+			return;
+	}
+	free(syms);
 
+	return;
+
+offset_overflow:
+	fprintf(stderr, "nm: %s: overflow in headers of archive\n",
+		fname);
 	return;
 
 too_big: