Skip to content
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

Use after free in match_at() #90

Open
mtasaka opened this issue Jun 16, 2017 · 0 comments
Open

Use after free in match_at() #90

mtasaka opened this issue Jun 16, 2017 · 0 comments
Labels

Comments

@mtasaka
Copy link

mtasaka commented Jun 16, 2017

Forwarded from kkos/oniguruma#61 , slightly modified for onigumo.
Test code:

#include <stdio.h>
#include "onigmo.h"
static int
scan_callback(OnigPosition n, OnigPosition r, OnigRegion* region, void* arg)
{
    return 0;
}

static int
scan(regex_t* reg, unsigned char* str, unsigned char* end)
{
  int r;
  OnigRegion *region;

  region = onig_region_new();

  r = onig_scan(reg, str, end, region, ONIG_OPTION_NONE, scan_callback, NULL);
  if (r >= 0) {
    fprintf(stdout, "total: %d match\n", r);
  }
  else { /* error */
    char s[ONIG_MAX_ERROR_MESSAGE_LEN];
    onig_error_code_to_str((OnigUChar* )s, r);
    fprintf(stderr, "ERROR: %s\n", s);
    return -1;
  }

  onig_region_free(region, 1 /* 1:free self, 0:free contents only */);
  return 0;
}

static int
exec(OnigEncoding enc, OnigOptionType options,
     char* apattern, char* astr,  int pattern_len,
    unsigned char *end, const OnigSyntaxType* sytax)
{
    int r;
    regex_t* reg;
    OnigErrorInfo einfo;
    UChar* pattern = (UChar* )apattern;
    UChar* str     = (UChar* )astr;

    onig_initialize(&enc, 1);

    r = onig_new(&reg, pattern,
                 pattern + pattern_len,
                 options, enc, sytax , &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;
    }

    r = scan(reg, str, end);
    onig_free(reg);
    onig_end();
    return 0;
}

extern int main(int argc, char* argv[])
{
    int r;
    /* ISO 8859-1 test */
    static unsigned char str[] = { 0xc7, 0xd6, 0xfe, 0xea, 0xe0, 0xe2, 0x00 };
    char* pattern ="\x28\x7c\x28\x00\x28\x3f\x3a\x5c\x67\x27\x31\x27\x29\x2a\x7c\x7c\x28\x29\x29\x2a\x7c\x28\x28\x28\x28\x29\x29\x29\x5c\x6b\x27\x31\x2d\x30\x27\x29\x29\x30\x7c";
    r = exec(ONIG_ENCODING_EUC_JP,ONIG_OPTION_NONE,pattern,(char*) str,39, str + 7, ONIG_SYNTAX_DEFAULT);
    return r;
}

With gdb:

[mtasaka@localhost _BUILDDIR]$ LD_LIBRARY_PATH=.libs gdb ./issue61-onigumo 
GNU gdb (GDB) Fedora 8.0-13.fc26
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./issue61-onigumo...done.
(gdb) r
Starting program: /home/mtasaka/rpmbuild/TEMP/onigumo/GIT/Onigmo/_BUILDDIR/issue61-onigumo 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b5377f in match_at (reg=0x603010, str=0x602064 <str> "\307\326\376\352\340", <incomplete sequence \342>, end=0x60206b "", 
    right_range=0x60206b "", sstart=0x60206a <str+6> "", sprev=0x60206a <str+6> "", msa=0x7fffffffd940)
    at /home/mtasaka/rpmbuild/TEMP/onigumo/GIT/Onigmo/_BUILDDIR/../regexec.c:2813
2813		STACK_NULL_CHECK_MEMST_REC(isnull, mem, s, reg);
(gdb) bt
#0  0x00007ffff7b5377f in match_at (reg=0x603010, str=0x602064 <str> "\307\326\376\352\340", <incomplete sequence \342>, end=0x60206b "", 
    right_range=0x60206b "", sstart=0x60206a <str+6> "", sprev=0x60206a <str+6> "", msa=0x7fffffffd940)
    at /home/mtasaka/rpmbuild/TEMP/onigumo/GIT/Onigmo/_BUILDDIR/../regexec.c:2813
#1  0x00007ffff7b59601 in onig_search_gpos (reg=0x603010, str=0x602064 <str> "\307\326\376\352\340", <incomplete sequence \342>, end=0x60206b "", 
    global_pos=0x60206a <str+6> "", start=0x60206a <str+6> "", range=0x60206b "", region=0x603be0, option=0)
    at /home/mtasaka/rpmbuild/TEMP/onigumo/GIT/Onigmo/_BUILDDIR/../regexec.c:4416
#2  0x00007ffff7b5893c in onig_search (reg=0x603010, str=0x602064 <str> "\307\326\376\352\340", <incomplete sequence \342>, end=0x60206b "", 
    start=0x60206a <str+6> "", range=0x60206b "", region=0x603be0, option=0)
    at /home/mtasaka/rpmbuild/TEMP/onigumo/GIT/Onigmo/_BUILDDIR/../regexec.c:4145
#3  0x00007ffff7b59cb2 in onig_scan (reg=0x603010, str=0x602064 <str> "\307\326\376\352\340", <incomplete sequence \342>, end=0x60206b "", 
    region=0x603be0, option=0, scan_callback=0x400937 <scan_callback>, callback_arg=0x0)
    at /home/mtasaka/rpmbuild/TEMP/onigumo/GIT/Onigmo/_BUILDDIR/../regexec.c:4535
#4  0x00000000004009a2 in scan (reg=0x603010, str=0x602064 <str> "\307\326\376\352\340", <incomplete sequence \342>, end=0x60206b "")
    at ./issue61-onigumo.c:17
#5  0x0000000000400b2e in exec (enc=0x602080 <OnigEncodingEUC_JP>, options=0, apattern=0x400c60 "(|(", 
    astr=0x602064 <str> "\307\326\376\352\340", <incomplete sequence \342>, pattern_len=39, end=0x60206b "", sytax=0x7ffff7b69220 <OnigSyntaxRuby>)
    at ./issue61-onigumo.c:55
#6  0x0000000000400b95 in main (argc=1, argv=0x7fffffffdd18) at ./issue61-onigumo.c:67

git bisect:

[mtasaka@localhost Onigmo]$ git bisect start 4ec6283275f09f038fd7ca23dce3de8e873e7b2c 7291b8a97c66aea96d74fba35a5e883a09bdf467
Previous HEAD position was 3ddfbfc... Merge branch 'topic/codecov'
Switched to branch 'localwork'
Bisecting: 39 revisions left to test after this (roughly 5 steps)
[8d0f9d3c20134e204e6913b9f1e7779f49f9d58f] Add documents for absent operator (Issue #82)
[mtasaka@localhost Onigmo]$ git bisect run ./bysect-onigumo.sh
4bd79e2d0039a44d3f736ede00baf81820a290fc is the first bad commit
commit 4bd79e2d0039a44d3f736ede00baf81820a290fc
Author: K.Takata <[email protected]>
Date:   Wed Dec 7 21:53:11 2016 +0900

    Better fix for Issue #48
    
    This partly reverts 7591b3ccd88a9dc1a482763a72783ecb2863a754.
    Also related: dd4638c9235381aa2363484a869628d71e8eea68

:100644 100644 32807be0478459a867c37aaa06371aed0e125bf8 fa27d6434dc27fbea0134df5fa66270bd6bba8aa M	regcomp.c
:100644 100644 74dade45fc721c3e0f56145a4031c180605b2059 b27884b32c4827d430613577d924e1362cce9748 M	regexec.c
bisect run success

It shows 4bd79e2 is the first bad commit.

@k-takata k-takata added the bug label Jan 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants