Skip to content

Commit 1ce2e32

Browse files
committed
Fix malformed addinstr crash (ref: #43)
instr->instr_size was not being checked, and as a result an abnormally long .addinstr would result in the following for loop modifying instr->args, and possibly other parts of the memory. This was fixed by checking to make sure that instr->instr_size was 8 or below, and if not, failing. As a result of a addinstr being possibly invalid, errors.h was updated to reflect a possibly invalid addinstr.
1 parent 0045bde commit 1ce2e32

File tree

2 files changed

+5
-1
lines changed

2 files changed

+5
-1
lines changed

directive.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ char *handle_directive (const char *ptr) {
163163
conv_hex (word, word + strlen (word), &result);
164164
instr->instr_size = strlen (word) / 2;
165165

166+
// Sanity check: are we within the upper bound?
167+
// (If not, fail - otherwise we start overwriting memory)
168+
if (instr->instr_size > 8) goto addinstr_fail;
169+
166170
for (j = instr->instr_size - 1; j >= 0; j--)
167171
instr->instr_data[instr->instr_size - j - 1] = (result >> (j * 8)) & 0xFF;
168172

errors.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ SPASMERROR g_ErrorCodes[]
108108
{SPASM_ERR_NO_PREVIOUS_DEFINE, _T("No previous define to continue")},
109109
{SPASM_ERR_ELIF_WITHOUT_IF, _T("Use of #ELIF outside of an #IF expression")},
110110
{SPASM_ERR_INVALID_OPTION, _T("The option %s does not exist")},
111-
{SPASM_ERR_INVALID_ADDINSTR, _T("Missing required information for .ADDINSTR")},
111+
{SPASM_ERR_INVALID_ADDINSTR, _T("Required information for .ADDINSTR is missing or invalid")},
112112
{SPASM_ERR_INVALID_RST_OPERANDS, _T("Invalid operands for the RST command")},
113113
{SPASM_ERR_DEFINE_HAS_NO_VALUE, _T("The define '%s' has been used, but doesn't have a value")},
114114
{SPASM_ERR_RECURSION_DEPTH, _T("Expression is too deep (only %d levels allowed)")},

0 commit comments

Comments
 (0)