Skip to content

Commit debdbe7

Browse files
committed
thcrap: Avoid potential out of bounds read on single 0 address strings
1 parent f276c7d commit debdbe7

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

thcrap/src/str_to_addr.asm

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static std::pair<uintptr_t, const char*> TH_FASTCALL str_to_addr_impl(uintptr_t
3232
flags = 0;
3333
TH_FALLTHROUGH;
3434
case '0':
35-
switch (*++str_read) {
35+
switch (c = *++str_read) {
3636
case 'x': case 'X':
3737
number_base = 16;
3838
c = *++str_read;
@@ -42,10 +42,9 @@ static std::pair<uintptr_t, const char*> TH_FASTCALL str_to_addr_impl(uintptr_t
4242
c = *++str_read;
4343
break;
4444
default:
45-
if (!flags) {
46-
goto fail;
47-
}
48-
TH_FALLTHROUGH;
45+
return flags == is_not_relative
46+
? std::make_pair(0, (const char*)str_read)
47+
: std::make_pair(std::numeric_limits<uintptr_t>::max(), str);
4948
case '0' ... '9':
5049
break;
5150
}
@@ -126,31 +125,28 @@ fail:
126125
LEA EAX, [ECX-'1']
127126
CMP AL, 9
128127
JB is_base_ten
129-
CMP AL, '0'-'1'
128+
CMP CL, '0'
130129
JE is_leading_zero
131130
OR CL, 0x20
132131
CMP CL, 'r'
133132
JNE failA
134133
XOR BL, BL
135134
is_leading_zero:
136135
MOVZX ECX, BYTE PTR [EDX+1]
137-
INC ESI
136+
ADD ESI, 1
138137
LEA EAX, [ECX-'0']
139138
CMP AL, 10
140139
JB is_base_ten
141140
MOV BH, 16
142141
OR CL, 0x20
143142
CMP CL, 'x'
144143
JE is_zero_prefix
145-
MOV BH, 2
146144
CMP CL, 'b'
147-
JE is_zero_prefix
148-
TEST BL, BL /* Make sure that a single 0 is valid but a single R is not */
149-
JZ failA
150-
DEC ESI /* Don't index the string twice if there isn't a b/x character */
145+
JNE standalone_zero
146+
MOV BH, 2
151147
is_zero_prefix:
152148
MOVZX ECX, BYTE PTR [EDX+2]
153-
INC ESI
149+
ADD ESI, 1
154150
is_base_ten:
155151
/*
156152
; EAX: ret
@@ -219,3 +215,14 @@ failA:
219215
POP EBX
220216
RET
221217
INT3
218+
INT3
219+
standalone_zero:
220+
CMP BL, 1 /* Make sure that a single 0 is valid but a single R is not */
221+
CMOVE EDX, ESI
222+
SBB EAX, EAX /* Returns 0 or -1 */
223+
POP EDI
224+
POP ESI
225+
POP EBP
226+
POP EBX
227+
RET
228+
INT3

0 commit comments

Comments
 (0)