Headline
CVE-2022-38890: Another way to trigger SEGV in njs_utf8_next cause oob read · Issue #569 · nginx/njs
Nginx NJS v0.7.7 was discovered to contain a segmentation violation via njs_utf8_next at src/njs_utf8.h
Demo patch
diff --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.