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: