Prevent buffer overrun in regparse.c

A regexp that ends with an escape following an incomplete UTF-8 char
might cause buffer overrun. Found by OSS-Fuzz.

```
$ valgrind ./miniruby -e 'Regexp.new("\\u2d73\\0\\0\\0\\0          \\\xE6".b)'
==296213== Memcheck, a memory error detector
==296213== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==296213== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==296213== Command: ./miniruby -e Regexp.new("\\\\u2d73\\\\0\\\\0\\\\0\\\\0\ \ \ \ \ \ \ \ \ \ \\\\\\xE6".b)
==296213==
==296213== Warning: client switching stacks?  SP change: 0x1ffe8020e0 --> 0x1ffeffff10
==296213==          to suppress, use: --max-stackframe=8379952 or greater
==296213== Invalid read of size 1
==296213==    at 0x484EA10: memmove (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==296213==    by 0x339568: memcpy (string_fortified.h:29)
==296213==    by 0x339568: onig_strcpy (regparse.c:271)
==296213==    by 0x339568: onig_node_str_cat (regparse.c:1413)
==296213==    by 0x33CBA0: parse_exp (regparse.c:6198)
==296213==    by 0x33EDE4: parse_branch (regparse.c:6511)
==296213==    by 0x33EEA2: parse_subexp (regparse.c:6544)
==296213==    by 0x34019C: parse_regexp (regparse.c:6593)
==296213==    by 0x34019C: onig_parse_make_tree (regparse.c:6638)
==296213==    by 0x32782D: onig_compile_ruby (regcomp.c:5779)
==296213==    by 0x313EFA: onig_new_with_source (re.c:876)
==296213==    by 0x313EFA: make_regexp (re.c:900)
==296213==    by 0x313EFA: rb_reg_initialize (re.c:3136)
==296213==    by 0x318555: rb_reg_initialize_str (re.c:3170)
==296213==    by 0x318555: rb_reg_init_str (re.c:3205)
==296213==    by 0x31A669: rb_reg_initialize_m (re.c:3856)
==296213==    by 0x3E5165: vm_call0_cfunc_with_frame (vm_eval.c:150)
==296213==    by 0x3E5165: vm_call0_cfunc (vm_eval.c:164)
==296213==    by 0x3E5165: vm_call0_body (vm_eval.c:210)
==296213==    by 0x3E89BD: vm_call0_cc (vm_eval.c:87)
==296213==    by 0x3E89BD: rb_call0 (vm_eval.c:551)
==296213==  Address 0x9d45b10 is 0 bytes after a block of size 32 alloc'd
==296213==    at 0x4844899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==296213==    by 0x20FA7B: objspace_xmalloc0 (gc.c:12146)
==296213==    by 0x35F8C9: str_buf_cat4.part.0 (string.c:3132)
==296213==    by 0x31359D: unescape_escaped_nonascii (re.c:2690)
==296213==    by 0x313A9D: unescape_nonascii (re.c:2869)
==296213==    by 0x313A9D: rb_reg_preprocess (re.c:2992)
==296213==    by 0x313DFC: rb_reg_initialize (re.c:3109)
==296213==    by 0x318555: rb_reg_initialize_str (re.c:3170)
==296213==    by 0x318555: rb_reg_init_str (re.c:3205)
==296213==    by 0x31A669: rb_reg_initialize_m (re.c:3856)
==296213==    by 0x3E5165: vm_call0_cfunc_with_frame (vm_eval.c:150)
==296213==    by 0x3E5165: vm_call0_cfunc (vm_eval.c:164)
==296213==    by 0x3E5165: vm_call0_body (vm_eval.c:210)
==296213==    by 0x3E89BD: vm_call0_cc (vm_eval.c:87)
==296213==    by 0x3E89BD: rb_call0 (vm_eval.c:551)
==296213==    by 0x3E957B: rb_call (vm_eval.c:877)
==296213==    by 0x3E957B: rb_funcallv_kw (vm_eval.c:1074)
==296213==    by 0x2A4123: rb_class_new_instance_pass_kw (object.c:1991)
==296213==
==296213==
==296213== HEAP SUMMARY:
==296213==     in use at exit: 35,476,538 bytes in 9,489 blocks
==296213==   total heap usage: 14,893 allocs, 5,404 frees, 37,517,821 bytes allocated
==296213==
==296213== LEAK SUMMARY:
==296213==    definitely lost: 316,081 bytes in 2,989 blocks
==296213==    indirectly lost: 136,808 bytes in 2,361 blocks
==296213==      possibly lost: 1,048,624 bytes in 3 blocks
==296213==    still reachable: 33,975,025 bytes in 4,136 blocks
==296213==         suppressed: 0 bytes in 0 blocks
==296213== Rerun with --leak-check=full to see details of leaked memory
==296213==
==296213== For lists of detected and suppressed errors, rerun with: -s
==296213== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
```
This commit is contained in:
Yusuke Endoh 2022-10-25 13:20:25 +09:00 коммит произвёл GitHub
Родитель ee3da3784e
Коммит 902e459b73
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 1 добавлений и 0 удалений

Просмотреть файл

@ -3799,6 +3799,7 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
}
else { /* string */
p = tok->backp + enclen(enc, tok->backp, end);
if (p > end) return ONIGERR_END_PATTERN_AT_ESCAPE;
}
}
break;