summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-08-08 13:49:00 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-08-08 13:49:00 -0700
commit8bec2c788f3432f24788a2e7487486e20543e063 (patch)
tree8c50c042f074a1856d402904019b993bd3aa3c8d
parentf903da144d8d521cacf2789a5b6755d9cb63b0d9 (diff)
downloadnasm-8bec2c788f3432f24788a2e7487486e20543e063.tar.gz
nasm-8bec2c788f3432f24788a2e7487486e20543e063.tar.bz2
nasm-8bec2c788f3432f24788a2e7487486e20543e063.zip
nasm.c: fix stack overrun in assemble_file
If [DEBUG id] has id longer then 80 symbols (well, 79 actually plus EOS) then stack will be just overwritten. Fix it with explicit check for identifier being too long. Based on an initial version by Cyrill Gorcunov <gorcunov@gmail.com>. Signed-off-by: H. Peter Anvin <hpa@zytor.com> Cc: Cyrill Gorcunov <gorcunov@gmail.com>
-rw-r--r--nasm.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/nasm.c b/nasm.c
index 8d72835..7bf7c57 100644
--- a/nasm.c
+++ b/nasm.c
@@ -1162,7 +1162,7 @@ static enum directives getkw(char **directive, char **value);
static void assemble_file(char *fname, StrList **depend_ptr)
{
- char *directive, *value, *p, *q, *special, *line, debugid[80];
+ char *directive, *value, *p, *q, *special, *line;
insn output_ins;
int i, validid;
bool rn_error;
@@ -1395,27 +1395,43 @@ static void assemble_file(char *fname, StrList **depend_ptr)
location.segment = NO_SEG;
break;
case D_DEBUG: /* [DEBUG] */
+ {
+ char debugid[128];
+ bool badid, overlong;
+
p = value;
q = debugid;
- validid = true;
- if (!isidstart(*p))
- validid = false;
- while (*p && !nasm_isspace(*p)) {
- if (!isidchar(*p))
- validid = false;
- *q++ = *p++;
- }
- *q++ = 0;
- if (!validid) {
- nasm_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC,
- "identifier expected after DEBUG");
- break;
- }
+ badid = overlong = false;
+ if (!isidstart(*p)) {
+ badid = true;
+ } else {
+ while (*p && !nasm_isspace(*p)) {
+ if (q >= debugid + sizeof debugid - 1) {
+ overlong = true;
+ break;
+ }
+ if (!isidchar(*p))
+ badid = true;
+ *q++ = *p++;
+ }
+ *q = 0;
+ }
+ if (badid) {
+ nasm_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC,
+ "identifier expected after DEBUG");
+ break;
+ }
+ if (overlong) {
+ nasm_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC,
+ "DEBUG identifier too long");
+ break;
+ }
while (*p && nasm_isspace(*p))
p++;
if (pass0 == 2)
dfmt->debug_directive(debugid, p);
break;
+ }
case D_WARNING: /* [WARNING {+|-|*}warn-name] */
while (*value && nasm_isspace(*value))
value++;