New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Another way to trigger SEGV in njs_utf8_next cause oob read #569
Comments
AnalysisThe root case is const u_char *
njs_string_offset(const u_char *start, const u_char *end, size_t index)
{
uint32_t *map;
njs_uint_t skip;
if (index >= NJS_STRING_MAP_STRIDE) {
map = njs_string_map_start(end); [1]<--- create and init map
if (map[0] == 0) {
njs_string_offset_map_init(start, end - start); [2]<----- calculate some value and assign to map
}
start += map[index / NJS_STRING_MAP_STRIDE - 1]; [3]<------- add map with start, **access array without check index**
}
for (skip = index % NJS_STRING_MAP_STRIDE; skip != 0; skip--) {
start = njs_utf8_next(start, end); [4] <----- crash here
}
return start;
} We can control pwndbg> p map
$37 = (uint32_t *) 0x617000002214
pwndbg> x/20gx 0x617000002214
0x617000002214: 0xbebebebe00000000 0xbebebebebebebebe
0x617000002224: 0xbebebebebebebebe 0xbebebebebebebebe
0x617000002234: 0xbebebebebebebebe 0xbebebebebebebebe
0x617000002244: 0xbebebebebebebebe 0x00000040bebebebe
0x617000002254: 0x0000004000006100 0x000004a000006100
0x617000002264: 0xbebe020100006190 0x0000200000000250
0x617000002274: 0x0000000000006170 0x0000000000000000
0x617000002284: 0x0000000000000000 0x0000000000000000
0x617000002294: 0x0000000000000000 0x0000000000000000
0x6170000022a4: 0x0000000000000000 0x0000000000000000 And after some process of pwndbg> p map
$36 = (uint32_t *) 0x617000002214
pwndbg> x/20gx 0x617000002214
0x617000002214: 0x000000c000000060 0x0000018000000120
0x617000002224: 0xbebebebe000001e0 0xbebebebebebebebe
0x617000002234: 0xbebebebebebebebe 0xbebebebebebebebe
0x617000002244: 0xbebebebebebebebe 0x00000040bebebebe
0x617000002254: 0x0000004000006100 0x000004a000006100
0x617000002264: 0xbebe020100006190 0x0000200000000250
0x617000002274: 0x0000000000006170 0x0000000000000000
0x617000002284: 0x0000000000000000 0x0000000000000000
0x617000002294: 0x0000000000000000 0x0000000000000000
0x6170000022a4: 0x0000000000000000 0x0000000000000000
In poc |
Demo patchdiff --git a/src/njs_string.c b/src/njs_string.c
index 83cede5..8b3a31e 100644
--- a/src/njs_string.c
+++ b/src/njs_string.c
@@ -2307,7 +2307,10 @@ njs_string_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args,
}
p = njs_string_offset(string.start, end, index);
-
+ if (p == (u_char*)NJS_ERROR) {
+ njs_error(vm, "index too large");
+ return NJS_ERROR;
+ }
for (; p >= string.start; p = njs_utf8_prev(p)) {
if ((p + s.size) <= end && memcmp(p, s.start, s.size) == 0) {
goto done;
@@ -2530,14 +2533,16 @@ njs_string_offset(const u_char *start, const u_char *end, size_t index)
{
uint32_t *map;
njs_uint_t skip;
-
+ njs_uint_t size = 0;
if (index >= NJS_STRING_MAP_STRIDE) {
map = njs_string_map_start(end);
if (map[0] == 0) {
- njs_string_offset_map_init(start, end - start);
+ size = njs_string_offset_map_init(start, end - start);
+ }
+ if((index / NJS_STRING_MAP_STRIDE) > size){
+ return (u_char*)NJS_ERROR;
}
-
start += map[index / NJS_STRING_MAP_STRIDE - 1];
}
@@ -2596,7 +2601,7 @@ njs_string_index(njs_string_prop_t *string, uint32_t offset)
}
-void
+njs_uint_t
njs_string_offset_map_init(const u_char *start, size_t size)
{
size_t offset;
@@ -2622,6 +2627,8 @@ njs_string_offset_map_init(const u_char *start, size_t size)
offset--;
} while (p < end);
+
+ return n;
}
diff --git a/src/njs_string.h b/src/njs_string.h
index 99f9d14..7e5eaab 100644
--- a/src/njs_string.h
+++ b/src/njs_string.h
@@ -244,7 +244,7 @@ njs_int_t njs_string_slice(njs_vm_t *vm, njs_value_t *dst,
const u_char *njs_string_offset(const u_char *start, const u_char *end,
size_t index);
uint32_t njs_string_index(njs_string_prop_t *string, uint32_t offset);
-void njs_string_offset_map_init(const u_char *start, size_t size);
+njs_uint_t njs_string_offset_map_init(const u_char *start, size_t size);
double njs_string_to_index(const njs_value_t *value);
const char *njs_string_to_c_string(njs_vm_t *vm, njs_value_t *value);
njs_int_t njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args,
This fix is not standard, I just provides an idea. |
the call stack is different with #522
Poc
Asan
Credit
ret2ddme
The text was updated successfully, but these errors were encountered: