Bug 18040 - use-after-free in regexec/get_subexp
Summary: use-after-free in regexec/get_subexp
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: regex (show other bugs)
Version: 2.21
: P2 normal
Target Milestone: 2.29
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 23609 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-02-26 21:31 UTC by Kostya Serebryany
Modified: 2018-12-16 15:16 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
konstantin.s.serebryany: security+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kostya Serebryany 2015-02-26 21:31:05 UTC
#include <regex.h>
#include <stdio.h>
int main() {
  regex_t r;
  char *p  = "!(.*)*\\*)\\1";
  char *s = "!!(.*)*\\*)\\1";
  if (!regcomp(&r, p, REG_ICASE | REG_EXTENDED))
    regexec(&r, s, 0, 0, 0);
  regfree(&r);
  return 0;
} 

% gcc -c  re2.c  && valgrind -q  ./a.out
==38369== Invalid read of size 1
==38369==    at 0x4F11FEC: get_subexp (regexec.c:2788)
==38369==    by 0x4F11FEC: transit_state_bkref (regexec.c:2603)
==38369==    by 0x4F1438A: merge_state_with_log (regexec.c:2384)
==38369==    by 0x4F1438A: check_matching (regexec.c:1160)
==38369==    by 0x4F1438A: re_search_internal (regexec.c:829)
==38369==    by 0x4F19D84: regexec@@GLIBC_2.3.4 (regexec.c:253)
clang/fuzz/a.out)
==38369==  Address 0x51fd1d8 is 8 bytes inside a block of size 11 free'd
==38369==    at 0x4C2CB0A: realloc (vg_replace_malloc.c:692)
==38369==    by 0x4F0ADE3: re_string_realloc_buffers (regex_internal.c:157)
==38369==    by 0x4F0ADE3: extend_buffers (regexec.c:4110)
==38369==    by 0x4F11B84: clean_state_log_if_needed (regexec.c:1728)
==38369==    by 0x4F11B84: get_subexp_sub.isra.27 (regexec.c:2852)
==38369==    by 0x4F120FE: get_subexp (regexec.c:2819)
==38369==    by 0x4F120FE: transit_state_bkref (regexec.c:2603)
==38369==    by 0x4F1438A: merge_state_with_log (regexec.c:2384)
==38369==    by 0x4F1438A: check_matching (regexec.c:1160)
==38369==    by 0x4F1438A: re_search_internal (regexec.c:829)
==38369==    by 0x4F19D84: regexec@@GLIBC_2.3.4 (regexec.c:253)

2.19 and fresh trunk are affected. 

This is admittedly a use-after-realloc, so with a glibc's malloc it *may*
be hard to exploit, but if a different malloc is used this may become a true
use-after-free. So, conservatively applying security+. 

Found with the same fuzzer as bugs 18032, 18036, 18037
Comment 1 Florian Weimer 2015-03-19 14:53:07 UTC
Is it possible to trigger this without REG_EXTENDED and a back reference?

(“\1” in an ERE makes behavior undefined according to POSIX.)
Comment 2 Kostya Serebryany 2015-03-19 15:54:24 UTC
(In reply to Florian Weimer from comment #1)
> Is it possible to trigger this without REG_EXTENDED and a back reference?
> 
> (“\1” in an ERE makes behavior undefined according to POSIX.)

I don't think I've seen this w/o REG_EXTENDED, but let me re-run the fuzzer
with cflags=0
Comment 3 Kostya Serebryany 2015-03-19 16:19:58 UTC
A quick fuzzing session did not reveal this bug with cflags=0, 
but due to bug 18037 (and probably some other similar issues)
fuzzing is not very efficient.
Comment 4 eggert 2018-09-06 08:19:42 UTC
Assaf Gordon writes in <https://debbugs.gnu.org/32592#41> that this bug is fixed by Assaf's patch to Bug#23609. The two bug reports should be merged.
Comment 5 eggert 2018-12-15 21:38:02 UTC
*** Bug 23609 has been marked as a duplicate of this bug. ***
Comment 6 Sourceware Commits 2018-12-16 15:09:06 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  ef202e530c2384d6a47951ed1c6b63ed945e462f (commit)
       via  077caf61d867d4cab49b5aa42da1611868596fe7 (commit)
      from  0c1719e65b2a5a80331d4f635612799f853b0479 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=ef202e530c2384d6a47951ed1c6b63ed945e462f

commit ef202e530c2384d6a47951ed1c6b63ed945e462f
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Wed Sep 5 23:57:08 2018 -0700

    regex: fix storage-exhaustion error
    
    [BZ #18040]
    * posix/regexec.c (get_subexp):
    Do not continue if storage is exhausted.

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=077caf61d867d4cab49b5aa42da1611868596fe7

commit 077caf61d867d4cab49b5aa42da1611868596fe7
Author: Assaf Gordon <assafgordon@gmail.com>
Date:   Wed Sep 5 23:25:07 2018 -0700

    regex: fix heap-use-after-free error
    
    [BZ #18040]
    Problem reported by Saito Takaaki <tails.saito@gmail.com> in
    https://debbugs.gnu.org/32592
    Call stack get_subexp->get_subexp_sub->clean_state_log_if_needed may
    call extend_buffers which reallocates the re_string_t internal buffer.
    Local variable 'buf' was not updated in such case, resulting in
    use-after-free.
    * posix/regexec.c (get_subexp): Update 'buf' after call to
    get_subexp_sub.

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog       |   20 ++++++++++++++++++++
 posix/regexec.c |    3 +++
 2 files changed, 23 insertions(+), 0 deletions(-)
Comment 7 eggert 2018-12-16 15:16:17 UTC
Marking this bug as fixed.