commit 77fc1f4d9d2c406bf920784bc8ca84a77fd90963
parent fdba86b87f7644af81e57923f0b4e4f6e03dedfa
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 24 Nov 2017 20:14:27 +0100
[nm] Add more overflow tests to nm()
Diffstat:
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/nm/main.c b/nm/main.c
@@ -55,12 +55,15 @@ nm(char *fname, char *member, FILE *fp)
{
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 @@ nm(char *fname, char *member, FILE *fp)
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;
+
+ if (fseek(fp, off, SEEK_SET) < 0)
+ return;
- siz = n * sizeof(struct myrosym);
- syms = xmalloc(n);
+ syms = xmalloc(n * sizeof(struct myrosym));
+ for (i = 0; n--; ++i) {
+ if (rdmyrosym(fp, &syms[i]) < 0)
+ return;
+ }
+ free(syms);
- while (n--)
- ;
+ return;
+offset_overflow:
+ fprintf(stderr, "nm: %s: overflow in headers of archive\n",
+ fname);
return;
too_big: