scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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:
nm/main.c | 28+++++++++++++++++++++++-----
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: