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

memory leak in regex #17122

Open
chongwick opened this issue Dec 11, 2024 · 6 comments · May be fixed by #17132
Open

memory leak in regex #17122

chongwick opened this issue Dec 11, 2024 · 6 comments · May be fixed by #17132

Comments

@chongwick
Copy link

Description

The following code:

<?php
class __Get {
    public function __construct($b) {
        $this->b = $b;
    }
    public function __get($name) {
        if ($name == 'pattern') {
            $this->b ='|(?P<name>)(\d+)|';
        } elseif ($name =='match') {
            $this->b = array();
            $this->b[] = 0xffffffff;
        }
        return $this->b;
    }
}

$b = new __Get('');
$pattern = $b->__get('pattern');
preg_match($pattern, $b->__get('match')[0], $m);
var_dump($m);
?>

Resulted in this output:

==2984278==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 32 byte(s) in 1 object(s) allocated from:
    #0 0x14cdaed5b887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x55f20116b644 in __zend_malloc /home/dan/php-src/Zend/zend_alloc.c:3280
    #2 0x55f200a326c8 in zend_string_alloc /home/dan/php-src/Zend/zend_string.h:176
    #3 0x55f200a326c8 in zend_string_init /home/dan/php-src/Zend/zend_string.h:198
    #4 0x55f200a326c8 in make_subpats_table /home/dan/php-src/ext/pcre/php_pcre.c:544
    #5 0x55f200a326c8 in pcre_get_compiled_regex_cache_ex /home/dan/php-src/ext/pcre/php_pcre.c:847
    #6 0x55f200a385e4 in pcre_get_compiled_regex_cache /home/dan/php-src/ext/pcre/php_pcre.c:889
    #7 0x55f200a385e4 in php_do_pcre_match /home/dan/php-src/ext/pcre/php_pcre.c:1123
    #8 0x55f2013c3ee0 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER /home/dan/php-src/Zend/zend_vm_execute.h:1287
    #9 0x55f2013c3ee0 in execute_ex /home/dan/php-src/Zend/zend_vm_execute.h:58774
    #10 0x55f2013de490 in zend_execute /home/dan/php-src/Zend/zend_vm_execute.h:64206
    #11 0x55f2014f8645 in zend_execute_script /home/dan/php-src/Zend/zend.c:1934
    #12 0x55f2010214e6 in php_execute_script_ex /home/dan/php-src/main/main.c:2574
    #13 0x55f2014fce36 in do_cli /home/dan/php-src/sapi/cli/php_cli.c:935
    #14 0x55f2008683c2 in main /home/dan/php-src/sapi/cli/php_cli.c:1310
    #15 0x14cdae691d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)

SUMMARY: AddressSanitizer: 32 byte(s) leaked in 1 allocation(s).

But I expected this output instead:

PHP Version

8.4.1

Operating System

No response

@nielsdos
Copy link
Member

How exactly did you run this? And what build configuration did you use? I can't reproduce this locally.

@chongwick
Copy link
Author

USE_ZEND_ALLOC=1 ./php test.php
The only configuration was the address sanitizer.

@nielsdos
Copy link
Member

I tried with a couple of different build configurations, and with both USE_ZEND_ALLOC=0 and USE_ZEND_ALLOC=1, and it still doesn't reproduce on my system.
Is the reproducer complete?
Can you also please post your config.log ?

@chongwick
Copy link
Author

This is the complete reproducer.

config.log

@chongwick
Copy link
Author

Also, to be clear, USE_ZEND_ALLOC=0 memory leaks are irrelevant as they are typically false flags. Or am I wrong?

@nielsdos
Copy link
Member

For some reason this only triggers on release builds 🤔 I'll have a look tomorrow...

Also, to be clear, USE_ZEND_ALLOC=0 memory leaks are irrelevant as they are typically false flags. Or am I wrong?

More or less, it's more nuanced. USE_ZEND_ALLOC=0 disables Zend's memory manager in favor of the system allocator. This can allow more leak detection because ASAN only instruments the system allocator. However, this also disables the automatic freeing of memory when a request/script ends, so it will report false positives for script aborts like when a fatal error happens.

@nielsdos nielsdos self-assigned this Dec 11, 2024
nielsdos added a commit to nielsdos/php-src that referenced this issue Dec 12, 2024
Because the subpattern names are persistent, and the fact that the
symbol table destruction is skipped when using fast_shutdown,
this means the refcounts will not be updated for the destruction of
the arrays that hold the subpattern name keys.
To solve this, detect this situation and duplicate the strings.
@nielsdos nielsdos linked a pull request Dec 12, 2024 that will close this issue
nielsdos added a commit to nielsdos/php-src that referenced this issue Dec 12, 2024
Because the subpattern names are persistent, and the fact that the
symbol table destruction is skipped when using fast_shutdown,
this means the refcounts will not be updated for the destruction of
the arrays that hold the subpattern name keys.
To solve this, detect this situation and duplicate the strings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants