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

Out-of-bounds read in set_bm_skip() #81

Closed
rhenium opened this Issue Dec 13, 2016 · 1 comment

Comments

Projects
None yet
2 participants
@rhenium

rhenium commented Dec 13, 2016

The following code

#include <stdio.h>
#include <string.h>
#include "onigmo.h"

int main(int argc, char* argv[])
{
	int r;
	regex_t* reg;
	OnigErrorInfo einfo;

	UChar* pattern = (UChar* )"\\\xD3\xD5\xBE\x1E+";
	r = onig_new(&reg, pattern, pattern + strlen((char* )pattern),
		     ONIG_OPTION_DEFAULT, ONIG_ENCODING_EUC_JP, ONIG_SYNTAX_DEFAULT, &einfo);
	if (r != ONIG_NORMAL) {
		OnigUChar s[ONIG_MAX_ERROR_MESSAGE_LEN];
		onig_error_code_to_str(s, r, &einfo);
		fprintf(stderr, "ERROR: %s\n", s);
		return -1;
	}
	onig_free(reg);
	onig_end();
}

causes out-of-bounds heap read:

=================================================================
==13981==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000efd3 at pc 0x7f898811550c bp 0x7ffd279fb1c0 sp 0x7ffd279fb1b0
READ of size 1 at 0x60200000efd3 thread T0
    #0 0x7f898811550b in set_bm_skip /work/ref/Onigmo/regcomp.c:4252
    #1 0x7f898811c341 in set_optimize_exact_info /work/ref/Onigmo/regcomp.c:5294
    #2 0x7f898811cce5 in set_optimize_info_from_tree /work/ref/Onigmo/regcomp.c:5386
    #3 0x7f898811db90 in onig_compile /work/ref/Onigmo/regcomp.c:5798
    #4 0x7f898811e553 in onig_new /work/ref/Onigmo/regcomp.c:5938
    #5 0x400be1 in main /work/ref/Onigmo/sample/simple.c:12
    #6 0x7f8987d2d290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
    #7 0x4009d9 in _start (/work/ref/Onigmo/sample/.libs/simple+0x4009d9)

0x60200000efd3 is located 0 bytes to the right of 3-byte region [0x60200000efd0,0x60200000efd3)
allocated by thread T0 here:
    #0 0x7f89884aee60 in __interceptor_malloc /build/gcc-multilib/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:62
    #1 0x7f898811be9e in set_optimize_exact_info /work/ref/Onigmo/regcomp.c:5268
    #2 0x7f898811cce5 in set_optimize_info_from_tree /work/ref/Onigmo/regcomp.c:5386
    #3 0x7f898811db90 in onig_compile /work/ref/Onigmo/regcomp.c:5798
    #4 0x7f898811e553 in onig_new /work/ref/Onigmo/regcomp.c:5938
    #5 0x400be1 in main /work/ref/Onigmo/sample/simple.c:12
    #6 0x7f8987d2d290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)

SUMMARY: AddressSanitizer: heap-buffer-overflow /work/ref/Onigmo/regcomp.c:4252 in set_bm_skip
Shadow bytes around the buggy address:
  0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fff9df0: fa fa fa fa fa fa fa fa fa fa[03]fa fa fa 00 04
  0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==13981==ABORTING

(originally reported at https://bugs.ruby-lang.org/issues/12997)

Valgrind reports out-of-bounds memory access while creating a Regexp object with an invalid byte sequence:
$ valgrind ruby -e'Regexp.new("\\\xD3\xD5\xBE\x1E+".force_encoding("euc-jp"))'
==21986== Memcheck, a memory error detector
==21986== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==21986== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==21986== Command: ruby -eRegexp.new("\\\\\\xD3\\xD5\\xBE\\x1E+".force_encoding("euc-jp"))
==21986== 
==21986== Invalid read of size 1
==21986==    at 0x1EF7D0: set_bm_skip.isra.17 (regcomp.c:4271)
==21986==    by 0x1FC1FB: set_optimize_exact_info (regcomp.c:5310)
==21986==    by 0x1FC1FB: set_optimize_info_from_tree (regcomp.c:5396)
==21986==    by 0x1FC1FB: onig_compile (regcomp.c:5824)
==21986==    by 0x1E7C0C: onig_new_with_source (re.c:850)
==21986==    by 0x1E7C0C: make_regexp (re.c:874)
==21986==    by 0x1E7C0C: rb_reg_initialize (re.c:2681)
==21986==    by 0x1E7DEE: rb_reg_initialize_str (re.c:2715)
==21986==    by 0x1E8021: rb_reg_init_str (re.c:2751)
==21986==    by 0x1E8021: rb_reg_initialize_m (re.c:3293)
==21986==    by 0x2981AA: vm_call0_cfunc_with_frame (vm_eval.c:131)
==21986==    by 0x2981AA: vm_call0_cfunc (vm_eval.c:148)
==21986==    by 0x2981AA: vm_call0_body.constprop.142 (vm_eval.c:180)
==21986==    by 0x29897C: vm_call0 (vm_eval.c:61)
==21986==    by 0x29897C: rb_call0 (vm_eval.c:342)
==21986==    by 0x19BFA0: rb_class_new_instance (object.c:1895)
==21986==    by 0x2891D6: vm_call_cfunc_with_frame (vm_insnhelper.c:1752)
==21986==    by 0x2891D6: vm_call_cfunc (vm_insnhelper.c:1847)
==21986==    by 0x296A8D: vm_call_method_each_type (vm_insnhelper.c:2138)
==21986==    by 0x296FC2: vm_call_method (vm_insnhelper.c:2288)
==21986==    by 0x28FEC8: vm_exec_core (insns.def:1066)
==21986==  Address 0x73f7333 is 0 bytes after a block of size 3 alloc'd
==21986==    at 0x4C2AB8D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21986==    by 0x1FC083: set_optimize_exact_info (regcomp.c:5284)
==21986==    by 0x1FC083: set_optimize_info_from_tree (regcomp.c:5396)
==21986==    by 0x1FC083: onig_compile (regcomp.c:5824)
==21986==    by 0x1E7C0C: onig_new_with_source (re.c:850)
==21986==    by 0x1E7C0C: make_regexp (re.c:874)
==21986==    by 0x1E7C0C: rb_reg_initialize (re.c:2681)
==21986==    by 0x1E7DEE: rb_reg_initialize_str (re.c:2715)
==21986==    by 0x1E8021: rb_reg_init_str (re.c:2751)
==21986==    by 0x1E8021: rb_reg_initialize_m (re.c:3293)
==21986==    by 0x2981AA: vm_call0_cfunc_with_frame (vm_eval.c:131)
==21986==    by 0x2981AA: vm_call0_cfunc (vm_eval.c:148)
==21986==    by 0x2981AA: vm_call0_body.constprop.142 (vm_eval.c:180)
==21986==    by 0x29897C: vm_call0 (vm_eval.c:61)
==21986==    by 0x29897C: rb_call0 (vm_eval.c:342)
==21986==    by 0x19BFA0: rb_class_new_instance (object.c:1895)
==21986==    by 0x2891D6: vm_call_cfunc_with_frame (vm_insnhelper.c:1752)
==21986==    by 0x2891D6: vm_call_cfunc (vm_insnhelper.c:1847)
==21986==    by 0x296A8D: vm_call_method_each_type (vm_insnhelper.c:2138)
==21986==    by 0x296FC2: vm_call_method (vm_insnhelper.c:2288)
==21986==    by 0x28FEC8: vm_exec_core (insns.def:1066)
==21986== 
==21986== 
==21986== HEAP SUMMARY:
==21986==     in use at exit: 2,538,700 bytes in 17,476 blocks
==21986==   total heap usage: 43,758 allocs, 26,282 frees, 10,646,254 bytes allocated
==21986== 
==21986== LEAK SUMMARY:
==21986==    definitely lost: 349,991 bytes in 3,886 blocks
==21986==    indirectly lost: 474,023 bytes in 5,121 blocks
==21986==      possibly lost: 1,441,628 bytes in 7,599 blocks
==21986==    still reachable: 273,058 bytes in 870 blocks
==21986==         suppressed: 0 bytes in 0 blocks
==21986== Rerun with --leak-check=full to see details of leaked memory
==21986== 
==21986== For counts of detected and suppressed errors, rerun with: -v
==21986== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

k-takata added a commit that referenced this issue Dec 13, 2016

Fix out-of-bounds read in set_bm_skip() (Issue #81)
Note: with the following code, enclen() returns 2, not 1.

    p = "\xBE";
    len = enclen(ONIG_ENCODING_EUC_JP, p, p + 1);

Need to check the end of the string.
@k-takata

This comment has been minimized.

Show comment
Hide comment
@k-takata

k-takata Dec 13, 2016

Owner

Thank you for the report.
Should be fixed now.

Owner

k-takata commented Dec 13, 2016

Thank you for the report.
Should be fixed now.

@k-takata k-takata closed this Dec 13, 2016

@k-takata k-takata added the bug label Dec 13, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment