From 1085fd1ba932fcab619cf862d71e259f4430e016 Mon Sep 17 00:00:00 2001 From: krion Date: Fri, 17 Dec 2004 09:14:26 +0000 Subject: Change sprintf()/vsprintf() to snprintf()/vsnprintf() to prevent vulnerability for buffer overflow exploits. Bump PORTREVISION. Submitted by: azhe Obtained from: nasm CVS --- devel/nasm/Makefile | 2 +- devel/nasm/files/patch-disasm.c | 194 ++++++++++++++++++++++++++++++++++ devel/nasm/files/patch-disasm.h | 17 +++ devel/nasm/files/patch-labels.c | 23 ++++ devel/nasm/files/patch-listing.c | 14 +++ devel/nasm/files/patch-nasm.c | 14 +++ devel/nasm/files/patch-ndisasm.c | 18 ++++ devel/nasm/files/patch-preproc.c | 223 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 504 insertions(+), 1 deletion(-) create mode 100644 devel/nasm/files/patch-disasm.c create mode 100644 devel/nasm/files/patch-disasm.h create mode 100644 devel/nasm/files/patch-labels.c create mode 100644 devel/nasm/files/patch-listing.c create mode 100644 devel/nasm/files/patch-nasm.c create mode 100644 devel/nasm/files/patch-ndisasm.c create mode 100644 devel/nasm/files/patch-preproc.c (limited to 'devel/nasm') diff --git a/devel/nasm/Makefile b/devel/nasm/Makefile index de050e1020b..4c92b7bc081 100644 --- a/devel/nasm/Makefile +++ b/devel/nasm/Makefile @@ -7,7 +7,7 @@ PORTNAME= nasm PORTVERSION= 0.98.38 -PORTREVISION= 1 +PORTREVISION= 2 PORTEPOCH= 1 CATEGORIES= devel lang MASTER_SITES= ${MASTER_SITE_SOURCEFORGE} diff --git a/devel/nasm/files/patch-disasm.c b/devel/nasm/files/patch-disasm.c new file mode 100644 index 00000000000..cb014628b0d --- /dev/null +++ b/devel/nasm/files/patch-disasm.c @@ -0,0 +1,194 @@ + +$FreeBSD$ + +--- disasm.c.orig ++++ disasm.c +@@ -484,8 +484,8 @@ + return data - origdata; + } + +-long disasm (unsigned char *data, char *output, int segsize, long offset, +- int autosync, unsigned long prefer) ++long disasm (unsigned char *data, char *output, int outbufsize, int segsize, ++ long offset, int autosync, unsigned long prefer) + { + struct itemplate **p, **best_p; + int length, best_length = 0; +@@ -582,27 +582,34 @@ + + slen = 0; + ++ /* TODO: snprintf returns the value that the string would have if ++ * the buffer were long enough, and not the actual length of ++ * the returned string, so each instance of using the return ++ * value of snprintf should actually be checked to assure that ++ * the return value is "sane." Maybe a macro wrapper could ++ * be used for that purpose. ++ */ + if (lock) +- slen += sprintf(output+slen, "lock "); ++ slen += snprintf(output+slen, outbufsize-slen, "lock "); + for (i = 0; i < ins.nprefix; i++) + switch (ins.prefixes[i]) { +- case P_REP: slen += sprintf(output+slen, "rep "); break; +- case P_REPE: slen += sprintf(output+slen, "repe "); break; +- case P_REPNE: slen += sprintf(output+slen, "repne "); break; +- case P_A16: slen += sprintf(output+slen, "a16 "); break; +- case P_A32: slen += sprintf(output+slen, "a32 "); break; +- case P_O16: slen += sprintf(output+slen, "o16 "); break; +- case P_O32: slen += sprintf(output+slen, "o32 "); break; ++ case P_REP: slen += snprintf(output+slen, outbufsize-slen, "rep "); break; ++ case P_REPE: slen += snprintf(output+slen, outbufsize-slen, "repe "); break; ++ case P_REPNE: slen += snprintf(output+slen, outbufsize-slen, "repne "); break; ++ case P_A16: slen += snprintf(output+slen, outbufsize-slen, "a16 "); break; ++ case P_A32: slen += snprintf(output+slen, outbufsize-slen, "a32 "); break; ++ case P_O16: slen += snprintf(output+slen, outbufsize-slen, "o16 "); break; ++ case P_O32: slen += snprintf(output+slen, outbufsize-slen, "o32 "); break; + } + + for (i = 0; i < elements(ico); i++) + if ((*p)->opcode == ico[i]) { +- slen += sprintf(output+slen, "%s%s", icn[i], ++ slen += snprintf(output+slen, outbufsize-slen, "%s%s", icn[i], + whichcond(ins.condition)); + break; + } + if (i >= elements(ico)) +- slen += sprintf(output+slen, "%s", insn_names[(*p)->opcode]); ++ slen += snprintf(output+slen, outbufsize-slen, "%s", insn_names[(*p)->opcode]); + colon = FALSE; + length += data - origdata; /* fix up for prefixes */ + for (i=0; i<(*p)->operands; i++) { +@@ -633,14 +640,14 @@ + ins.oprs[i].basereg = whichreg ((*p)->opd[i], + ins.oprs[i].basereg); + if ( (*p)->opd[i] & TO ) +- slen += sprintf(output+slen, "to "); +- slen += sprintf(output+slen, "%s", ++ slen += snprintf(output+slen, outbufsize-slen, "to "); ++ slen += snprintf(output+slen, outbufsize-slen, "%s", + reg_names[ins.oprs[i].basereg-EXPR_REG_START]); + } else if (!(UNITY & ~(*p)->opd[i])) { + output[slen++] = '1'; + } else if ( (*p)->opd[i] & IMMEDIATE ) { + if ( (*p)->opd[i] & BITS8 ) { +- slen += sprintf(output+slen, "byte "); ++ slen += snprintf(output+slen, outbufsize-slen, "byte "); + if (ins.oprs[i].segment & SEG_SIGNED) { + if (ins.oprs[i].offset < 0) { + ins.oprs[i].offset *= -1; +@@ -649,17 +656,17 @@ + output[slen++] = '+'; + } + } else if ( (*p)->opd[i] & BITS16 ) { +- slen += sprintf(output+slen, "word "); ++ slen += snprintf(output+slen, outbufsize-slen, "word "); + } else if ( (*p)->opd[i] & BITS32 ) { +- slen += sprintf(output+slen, "dword "); ++ slen += snprintf(output+slen, outbufsize-slen, "dword "); + } else if ( (*p)->opd[i] & NEAR ) { +- slen += sprintf(output+slen, "near "); ++ slen += snprintf(output+slen, outbufsize-slen, "near "); + } else if ( (*p)->opd[i] & SHORT ) { +- slen += sprintf(output+slen, "short "); ++ slen += snprintf(output+slen, outbufsize-slen, "short "); + } +- slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); ++ slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); + } else if ( !(MEM_OFFS & ~(*p)->opd[i]) ) { +- slen += sprintf(output+slen, "[%s%s%s0x%lx]", ++ slen += snprintf(output+slen, outbufsize-slen, "[%s%s%s0x%lx]", + (segover ? segover : ""), + (segover ? ":" : ""), + (ins.oprs[i].addr_size == 32 ? "dword " : +@@ -669,30 +676,30 @@ + } else if ( !(REGMEM & ~(*p)->opd[i]) ) { + int started = FALSE; + if ( (*p)->opd[i] & BITS8 ) +- slen += sprintf(output+slen, "byte "); ++ slen += snprintf(output+slen, outbufsize-slen, "byte "); + if ( (*p)->opd[i] & BITS16 ) +- slen += sprintf(output+slen, "word "); ++ slen += snprintf(output+slen, outbufsize-slen, "word "); + if ( (*p)->opd[i] & BITS32 ) +- slen += sprintf(output+slen, "dword "); ++ slen += snprintf(output+slen, outbufsize-slen, "dword "); + if ( (*p)->opd[i] & BITS64 ) +- slen += sprintf(output+slen, "qword "); ++ slen += snprintf(output+slen, outbufsize-slen, "qword "); + if ( (*p)->opd[i] & BITS80 ) +- slen += sprintf(output+slen, "tword "); ++ slen += snprintf(output+slen, outbufsize-slen, "tword "); + if ( (*p)->opd[i] & FAR ) +- slen += sprintf(output+slen, "far "); ++ slen += snprintf(output+slen, outbufsize-slen, "far "); + if ( (*p)->opd[i] & NEAR ) +- slen += sprintf(output+slen, "near "); ++ slen += snprintf(output+slen, outbufsize-slen, "near "); + output[slen++] = '['; + if (ins.oprs[i].addr_size) +- slen += sprintf(output+slen, "%s", ++ slen += snprintf(output+slen, outbufsize-slen, "%s", + (ins.oprs[i].addr_size == 32 ? "dword " : + ins.oprs[i].addr_size == 16 ? "word " : "")); + if (segover) { +- slen += sprintf(output+slen, "%s:", segover); ++ slen += snprintf(output+slen, outbufsize-slen, "%s:", segover); + segover = NULL; + } + if (ins.oprs[i].basereg != -1) { +- slen += sprintf(output+slen, "%s", ++ slen += snprintf(output+slen, outbufsize-slen, "%s", + reg_names[(ins.oprs[i].basereg - + EXPR_REG_START)]); + started = TRUE; +@@ -700,11 +707,11 @@ + if (ins.oprs[i].indexreg != -1) { + if (started) + output[slen++] = '+'; +- slen += sprintf(output+slen, "%s", ++ slen += snprintf(output+slen, outbufsize-slen, "%s", + reg_names[(ins.oprs[i].indexreg - + EXPR_REG_START)]); + if (ins.oprs[i].scale > 1) +- slen += sprintf(output+slen, "*%d", ins.oprs[i].scale); ++ slen += snprintf(output+slen, outbufsize-slen, "*%d", ins.oprs[i].scale); + started = TRUE; + } + if (ins.oprs[i].segment & SEG_DISP8) { +@@ -713,20 +720,20 @@ + ins.oprs[i].offset = - (signed char) ins.oprs[i].offset; + sign = '-'; + } +- slen += sprintf(output+slen, "%c0x%lx", sign, ++ slen += snprintf(output+slen, outbufsize-slen, "%c0x%lx", sign, + ins.oprs[i].offset); + } else if (ins.oprs[i].segment & SEG_DISP16) { + if (started) + output[slen++] = '+'; +- slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); ++ slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); + } else if (ins.oprs[i].segment & SEG_DISP32) { + if (started) + output[slen++] = '+'; +- slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); ++ slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); + } + output[slen++] = ']'; + } else { +- slen += sprintf(output+slen, "", i); ++ slen += snprintf(output+slen, outbufsize-slen, "", i); + } + } + output[slen] = '\0'; +@@ -741,8 +748,8 @@ + return length; + } + +-long eatbyte (unsigned char *data, char *output) ++long eatbyte (unsigned char *data, char *output, int outbufsize) + { +- sprintf(output, "db 0x%02X", *data); ++ snprintf(output, outbufsize, "db 0x%02X", *data); + return 1; + } diff --git a/devel/nasm/files/patch-disasm.h b/devel/nasm/files/patch-disasm.h new file mode 100644 index 00000000000..3a1fd91bc29 --- /dev/null +++ b/devel/nasm/files/patch-disasm.h @@ -0,0 +1,17 @@ + +$FreeBSD$ + +--- disasm.h.orig ++++ disasm.h +@@ -11,8 +11,8 @@ + + #define INSN_MAX 32 /* one instruction can't be longer than this */ + +-long disasm (unsigned char *data, char *output, int segsize, long offset, +- int autosync, unsigned long prefer); +-long eatbyte (unsigned char *data, char *output); ++long disasm (unsigned char *data, char *output, int outbufsize, int segsize, ++ long offset, int autosync, unsigned long prefer); ++long eatbyte (unsigned char *data, char *output, int outbufsize); + + #endif diff --git a/devel/nasm/files/patch-labels.c b/devel/nasm/files/patch-labels.c new file mode 100644 index 00000000000..7f11aca39ad --- /dev/null +++ b/devel/nasm/files/patch-labels.c @@ -0,0 +1,23 @@ + +$FreeBSD$ + +--- labels.c.orig ++++ labels.c +@@ -221,7 +221,7 @@ + slen += strlen(lpostfix); + slen++; /* room for that null char */ + xsymbol = nasm_malloc(slen); +- sprintf(xsymbol,"%s%s%s",lprefix,lptr->defn.label,lpostfix); ++ snprintf(xsymbol,slen,"%s%s%s",lprefix,lptr->defn.label,lpostfix); + + ofmt->symdef (xsymbol, segment, offset, exi, + special ? special : lptr->defn.special); +@@ -286,7 +286,7 @@ + slen += strlen(lpostfix); + slen++; /* room for that null char */ + xsymbol = nasm_malloc(slen); +- sprintf(xsymbol,"%s%s%s",lprefix,lptr->defn.label,lpostfix); ++ snprintf(xsymbol,slen,"%s%s%s",lprefix,lptr->defn.label,lpostfix); + + ofmt->symdef (xsymbol, segment, offset, exi, + special ? special : lptr->defn.special); diff --git a/devel/nasm/files/patch-listing.c b/devel/nasm/files/patch-listing.c new file mode 100644 index 00000000000..f36d99db2a5 --- /dev/null +++ b/devel/nasm/files/patch-listing.c @@ -0,0 +1,14 @@ + +$FreeBSD$ + +--- listing.c.orig ++++ listing.c +@@ -192,7 +192,7 @@ + else if (typ == OUT_RESERVE) + { + char q[20]; +- sprintf(q, "", size); ++ snprintf(q, sizeof(q), "", size); + list_out (offset, q); + } + } diff --git a/devel/nasm/files/patch-nasm.c b/devel/nasm/files/patch-nasm.c new file mode 100644 index 00000000000..fd1ac27c84f --- /dev/null +++ b/devel/nasm/files/patch-nasm.c @@ -0,0 +1,14 @@ + +$FreeBSD$ + +--- nasm.c.orig ++++ nasm.c +@@ -185,7 +185,7 @@ + /* define some macros dependent of command-line */ + { + char temp [64]; +- sprintf (temp, "__OUTPUT_FORMAT__=%s\n", ofmt->shortname); ++ snprintf (temp, sizeof(temp), "__OUTPUT_FORMAT__=%s\n", ofmt->shortname); + pp_pre_define (temp); + } + diff --git a/devel/nasm/files/patch-ndisasm.c b/devel/nasm/files/patch-ndisasm.c new file mode 100644 index 00000000000..f714fb8c3c6 --- /dev/null +++ b/devel/nasm/files/patch-ndisasm.c @@ -0,0 +1,18 @@ + +$FreeBSD$ + +--- ndisasm.c.orig ++++ ndisasm.c +@@ -243,10 +243,10 @@ + nextsync = next_sync (offset, &synclen); + } + while (p > q && (p - q >= INSN_MAX || lenread == 0)) { +- lendis = disasm (q, outbuf, bits, offset, autosync, prefer); ++ lendis = disasm (q, outbuf, sizeof(outbuf), bits, offset, autosync, prefer); + if (!lendis || lendis > (p - q) || + (unsigned long)lendis > nextsync-offset) +- lendis = eatbyte (q, outbuf); ++ lendis = eatbyte (q, outbuf, sizeof(outbuf)); + output_ins (offset, q, lendis, outbuf); + q += lendis; + offset += lendis; diff --git a/devel/nasm/files/patch-preproc.c b/devel/nasm/files/patch-preproc.c new file mode 100644 index 00000000000..d75b4ccdb76 --- /dev/null +++ b/devel/nasm/files/patch-preproc.c @@ -0,0 +1,223 @@ + +$FreeBSD$ + +--- preproc.c.orig ++++ preproc.c +@@ -528,7 +528,7 @@ + fname++; + fnlen = strcspn(fname, "\""); + line = nasm_malloc(20 + fnlen); +- sprintf(line, "%%line %d %.*s", lineno, fnlen, fname); ++ snprintf(line, 20+fnlen,"%%line %d %.*s", lineno, fnlen, fname); + nasm_free(oldline); + } + if (tasm_compatible_mode) +@@ -833,6 +833,7 @@ + type = TOK_STRING; + while (*p && *p != c) + p++; ++ + if (*p) + { + p++; +@@ -840,6 +841,8 @@ + else + { + error(ERR_WARNING, "unterminated string"); ++ /* Handling unterminated strings by UNV */ ++ /* type = -1; */ + } + } + else if (isnumstart(*p)) +@@ -901,6 +904,15 @@ + } + p++; + } ++ ++ /* Handling unterminated string by UNV */ ++ /*if (type == -1) ++ { ++ *tail = t = new_Token(NULL, TOK_STRING, line, p-line+1); ++ t->text[p-line] = *line; ++ tail = &t->next; ++ } ++ else*/ + if (type != TOK_COMMENT) + { + *tail = t = new_Token(NULL, type, line, p - line); +@@ -919,20 +931,20 @@ + static void * + new_Block(size_t size) + { +- Blocks *b = &blocks; ++ Blocks *b = &blocks; + +- /* first, get to the end of the linked list */ +- while (b->next) +- b = b->next; +- /* now allocate the requested chunk */ +- b->chunk = nasm_malloc(size); ++ /* first, get to the end of the linked list */ ++ while (b->next) ++ b = b->next; ++ /* now allocate the requested chunk */ ++ b->chunk = nasm_malloc(size); + +- /* now allocate a new block for the next request */ +- b->next = nasm_malloc(sizeof(Blocks)); +- /* and initialize the contents of the new block */ +- b->next->next = NULL; +- b->next->chunk = NULL; +- return b->chunk; ++ /* now allocate a new block for the next request */ ++ b->next = nasm_malloc(sizeof(Blocks)); ++ /* and initialize the contents of the new block */ ++ b->next->next = NULL; ++ b->next->chunk = NULL; ++ return b->chunk; + } + + /* +@@ -941,22 +953,22 @@ + static void + delete_Blocks(void) + { +- Blocks *a,*b = &blocks; ++ Blocks *a,*b = &blocks; + +- /* +- * keep in mind that the first block, pointed to by blocks +- * is a static and not dynamically allocated, so we don't +- * free it. +- */ +- while (b) +- { +- if (b->chunk) +- nasm_free(b->chunk); +- a = b; +- b = b->next; +- if (a != &blocks) +- nasm_free(a); +- } ++ /* ++ * keep in mind that the first block, pointed to by blocks ++ * is a static and not dynamically allocated, so we don't ++ * free it. ++ */ ++ while (b) ++ { ++ if (b->chunk) ++ nasm_free(b->chunk); ++ a = b; ++ b = b->next; ++ if (a != &blocks) ++ nasm_free(a); ++ } + } + + /* +@@ -1043,7 +1055,7 @@ + char *p, *q = t->text + 2; + + q += strspn(q, "$"); +- sprintf(buffer, "..@%lu.", ctx->number); ++ snprintf(buffer, sizeof(buffer), "..@%lu.", ctx->number); + p = nasm_strcat(buffer, q); + nasm_free(t->text); + t->text = p; +@@ -1520,23 +1532,30 @@ + t = t->next; + continue; + } +- else if (tt->type == TOK_WHITESPACE) ++ if (tt->type == TOK_WHITESPACE) + { + tt = tt->next; + continue; + } +- else if (tt->type != t->type || +- mstrcmp(tt->text, t->text, casesense)) ++ if (tt->type != t->type) + { + j = FALSE; /* found mismatching tokens */ + break; + } +- else ++ /* Unify surrounding quotes for strings */ ++ if (t->type == TOK_STRING) + { +- t = t->next; +- tt = tt->next; +- continue; ++ tt->text[0] = t->text[0]; ++ tt->text[strlen(tt->text) - 1] = t->text[0]; + } ++ if (mstrcmp(tt->text, t->text, casesense) != 0) ++ { ++ j = FALSE; /* found mismatching tokens */ ++ break; ++ } ++ ++ t = t->next; ++ tt = tt->next; + } + if ((t->type != TOK_OTHER || strcmp(t->text, ",")) || tt) + j = FALSE; /* trailing gunk on one end or other */ +@@ -1954,7 +1973,7 @@ + free_tlist(tt); + + /* Now define the macro for the argument */ +- sprintf(directive, "%%define %s (%s+%d)", arg, StackPointer, ++ snprintf(directive, sizeof(directive), "%%define %s (%s+%d)", arg, StackPointer, + offset); + do_directive(tokenise(directive)); + offset += size; +@@ -2051,13 +2070,13 @@ + free_tlist(tt); + + /* Now define the macro for the argument */ +- sprintf(directive, "%%define %s (%s-%d)", local, StackPointer, ++ snprintf(directive, sizeof(directive), "%%define %s (%s-%d)", local, StackPointer, + offset); + do_directive(tokenise(directive)); + offset += size; + + /* Now define the assign to setup the enter_c macro correctly */ +- sprintf(directive, "%%assign %%$localsize %%$localsize+%d", ++ snprintf(directive, sizeof(directive), "%%assign %%$localsize %%$localsize+%d", + size); + do_directive(tokenise(directive)); + +@@ -3182,12 +3201,12 @@ + */ + case '0': + type = TOK_NUMBER; +- sprintf(tmpbuf, "%d", mac->nparam); ++ snprintf(tmpbuf, sizeof(tmpbuf), "%d", mac->nparam); + text = nasm_strdup(tmpbuf); + break; + case '%': + type = TOK_ID; +- sprintf(tmpbuf, "..@%lu.", mac->unique); ++ snprintf(tmpbuf, sizeof(tmpbuf), "..@%lu.", mac->unique); + text = nasm_strcat(tmpbuf, t->text + 2); + break; + case '-': +@@ -4067,7 +4086,7 @@ + return; + + va_start(arg, fmt); +- vsprintf(buff, fmt, arg); ++ vsnprintf(buff, sizeof(buff), fmt, arg); + va_end(arg); + + if (istk && istk->mstk && istk->mstk->name) +@@ -4530,7 +4549,7 @@ + make_tok_num(Token * tok, long val) + { + char numbuf[20]; +- sprintf(numbuf, "%ld", val); ++ snprintf(numbuf, sizeof(numbuf), "%ld", val); + tok->text = nasm_strdup(numbuf); + tok->type = TOK_NUMBER; + } -- cgit