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

Support hardened malloc #8940

Closed
cgzones opened this issue Jul 6, 2022 · 6 comments
Closed

Support hardened malloc #8940

cgzones opened this issue Jul 6, 2022 · 6 comments

Comments

@cgzones
Copy link

cgzones commented Jul 6, 2022

Description

When using hardened malloc php segfaults due to a report of double free or memory corruption from the hardened allocator:

Core was generated by `/usr/sbin/php-fpm8.1 --nodaemonize --fpm-config /etc/php/8.1/fpm/php-fpm.conf'.                                                                                                                                                                        
Program terminated with signal SIGABRT, Aborted.                                                                                                                                                                                                                              
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49                                                                                                                                                                                                     
49      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.                                                                                                                                                                                                        
(gdb) bt full                                                                                                                                                                                                                                                                 
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49                                                                                                                                                                                                     
        set = {__val = {68096, 128064363255532, 2090512752, 1, 128064350344860, 128064357541232, 1, 95230346296447, 720, 95230346296664, 127902518216960, 140731259452880, 127902518216960, 95230346296447, 140731259452880, 114599034921464}}                                
        pid = <optimized out>                                                                                                                                                                                                                                                 
        tid = <optimized out>                                                                                                                                                                                                                                                 
        ret = <optimized out>                                                                                                                                                                                                                                                 
#1  0x000074794e1e5546 in __GI_abort () at abort.c:79                                                                                                                                                                                                                         
        save_stage = 1                                                                                                                                                                                                                                                        
        act = {__sigaction_handler = {sa_handler = 0x7453a02a0900, sa_sigaction = 0x7453a02a0900}, sa_mask = {__val = {128064363158178, 140731259453312, 11151701787683411968, 115494027777088, 0, 95230347530624, 114956386561024, 114599035052984, 114956386561024,         
              115494027777024, 95230346354345, 115494027777088, 1, 95230348423520, 95230347472523, 115494027778112}}, sa_flags = 1, sa_restorer = 0x74794d931100 <class_PDOException_methods>}                                                                                
        sigs = {__val = {32, 128064363158178, 127902518225408, 32, 127902518225408, 128064363158178, 95230347712736, 7, 95230348722848, 320, 16, 16, 140731259453296, 114599035043296, 95230348423520, 95230346857943}}                                                       
#2  0x000074794e23ceb8 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x74794e35aa78 "%s\n") at ../sysdeps/posix/libc_fatal.c:155                                                                                                                             
        ap = {{gp_offset = 24, fp_offset = 0, overflow_arg_area = 0x7ffe8cba8080, reg_save_area = 0x7ffe8cba8010}}                                                                                                                                                            
        fd = <optimized out>                                                                                                                                                                                                                                                  
        list = <optimized out>
        nlist = <optimized out>
        cp = <optimized out>
#3  0x000074794e24491a in malloc_printerr (str=str@entry=0x74794e35cf80 "double free or corruption (out)") at malloc.c:5628
No locals.
#4  0x000074794e2461a0 in _int_free (av=0x74794e391ba0 <main_arena>, p=0x683a2ac6fe00, have_lock=<optimized out>) at malloc.c:4547
        size = 9174903411436676608
        fb = <optimized out>
        nextchunk = 0x7f543644e9fae400
        nextsize = <optimized out>
        nextinuse = <optimized out>
        prevsize = <optimized out>
        bck = <optimized out>
        fwd = <optimized out>
        __PRETTY_FUNCTION__ = "_int_free"
#5  0x000074794e2499b4 in __GI___libc_free (mem=<optimized out>) at malloc.c:3309                                                                                                                                                                                     [43/969]
        ar_ptr = <optimized out>
        p = <optimized out>
        hook = <optimized out>
        err = 2
#6  0x000074794d925888 in zend_string_release (s=0x683a2ac6fe10) at ./Zend/zend_string.h:322
No locals.
#7  register_class_PDOException (class_entry_RuntimeException=<optimized out>) at ./ext/pdo/pdo_arginfo.h:32
        ce = {type = 0 '\000', name = 0x683a2ac6fdb0, {parent = 0x0, parent_name = 0x0}, refcount = 0, ce_flags = 0, default_properties_count = 0, default_static_members_count = 0, default_properties_table = 0x0, default_static_members_table = 0x0, 
          static_members_table__ptr = 0x0, function_table = {gc = {refcount = 0, u = {type_info = 0}}, u = {v = {flags = 0 '\000', _unused = 0 '\000', nIteratorsCount = 0 '\000', _unused2 = 0 '\000'}, flags = 0}, nTableMask = 0, arData = 0x0, nNumUsed = 0, 
            nNumOfElements = 0, nTableSize = 0, nInternalPointer = 0, nNextFreeElement = 0, pDestructor = 0x0}, properties_info = {gc = {refcount = 0, u = {type_info = 0}}, u = {v = {flags = 0 '\000', _unused = 0 '\000', nIteratorsCount = 0 '\000', 
                _unused2 = 0 '\000'}, flags = 0}, nTableMask = 0, arData = 0x0, nNumUsed = 0, nNumOfElements = 0, nTableSize = 0, nInternalPointer = 0, nNextFreeElement = 0, pDestructor = 0x0}, constants_table = {gc = {refcount = 0, u = {type_info = 0}}, u = {v = {
                flags = 0 '\000', _unused = 0 '\000', nIteratorsCount = 0 '\000', _unused2 = 0 '\000'}, flags = 0}, nTableMask = 0, arData = 0x0, nNumUsed = 0, nNumOfElements = 0, nTableSize = 0, nInternalPointer = 0, nNextFreeElement = 0, pDestructor = 0x0}, 
          mutable_data__ptr = 0x0, inheritance_cache = 0x0, properties_info_table = 0x0, constructor = 0x0, destructor = 0x0, clone = 0x0, __get = 0x0, __set = 0x0, __unset = 0x0, __isset = 0x0, __call = 0x0, __callstatic = 0x0, __tostring = 0x0, __debugInfo = 0x0, 
          __serialize = 0x0, __unserialize = 0x0, iterator_funcs_ptr = 0x0, {create_object = 0x0, interface_gets_implemented = 0x0}, get_iterator = 0x0, get_static_method = 0x0, serialize = 0x0, unserialize = 0x0, num_interfaces = 0, num_traits = 0, {interfaces = 0x0, i
nterface_names = 0x0}, trait_names = 0x0, trait_aliases = 0x0, trait_precedences = 0x0, attributes = 0x0, enum_backing_type = 0, backed_enum_table = 0x0, info = {user = {filename = 0x74794d931100 <class_PDOException_methods>, line_start = 0, line_end = 0, doc_comment = 
0x0}, internal = {builtin_functions = 0x74794d931100 <class_PDOException_methods>, module = 0x0}}}
        class_entry = 0x690a8c7fd800
        property_code_default_value = {value = {lval = 0, dval = 0, counted = 0x0, str = 0x0, arr = 0x0, obj = 0x0, res = 0x0, ref = 0x0, ast = 0x0, zv = 0x0, ptr = 0x0, ce = 0x0, func = 0x0, ww = {w1 = 0, w2 = 0}}, u1 = {type_info = 4, v = {type = 4 '\004', type_flags 
= 0 '\000', u = {extra = 0}}}, u2 = {next = 22172, cache_slot = 22172, opline_num = 22172, lineno = 22172, num_args = 22172, fe_pos = 22172, fe_iter_idx = 22172, property_guard = 22172, constant_flags = 22172, extra = 22172}}
        property_code_name = 0x683a2ac6fe10
        property_errorInfo_default_value = {value = {lval = 0, dval = 0, counted = 0x0, str = 0x0, arr = 0x0, obj = 0x0, res = 0x0, ref = 0x0, ast = 0x0, zv = 0x0, ptr = 0x0, ce = 0x0, func = 0x0, ww = {w1 = 0, w2 = 0}}, u1 = {type_info = 717666512, v = {type = 208 '\32
0', type_flags = 184 '\270', u = {extra = 10950}}}, u2 = {next = 26682, cache_slot = 26682, opline_num = 26682, lineno = 26682, num_args = 26682, fe_pos = 26682, fe_iter_idx = 26682, property_guard = 26682, constant_flags = 26682, extra = 26682}}
        property_errorInfo_name = <optimized out>
#8  0x000074794d9258fc in zm_startup_pdo (type=<optimized out>, module_number=17) at ./ext/pdo/pdo.c:253
No locals.
#9  0x0000569c8af74d48 in zend_startup_module_ex (module=0x68a7d30ec900) at ./Zend/zend_API.c:2199
        name_len = <optimized out>
        lcname = <optimized out>
        name_len = <optimized out>
        lcname = <optimized out>
        dep = <optimized out>
        req_mod = <optimized out>
#10 zend_startup_module_ex (module=0x68a7d30ec900) at ./Zend/zend_API.c:2152
        name_len = <optimized out>
        lcname = <optimized out>
        dep = <optimized out>
        req_mod = <optimized out>
#11 0x0000569c8af74ddc in zend_startup_module_zval (zv=<optimized out>) at ./Zend/zend_API.c:2214
        module = <optimized out>
#12 0x0000569c8af82822 in zend_hash_apply (ht=ht@entry=0x569c8b1f32e0 <module_registry>, apply_func=apply_func@entry=0x569c8af74dd0 <zend_startup_module_zval>) at ./Zend/zend_hash.c:1862
        idx = 16
        p = 0x69a874180400
        result = <optimized out>
#13 0x0000569c8af7509b in zend_startup_modules () at ./Zend/zend_API.c:2325
No locals.
#14 0x0000569c8af0c613 in php_module_startup (sf=<optimized out>, additional_modules=additional_modules@entry=0x569c8b1dab00 <cgi_module_entry>, num_additional_modules=num_additional_modules@entry=1) at ./main/main.c:2256
        zuf = {error_function = 0x569c8ad94aef <php_error_cb>, printf_function = 0x569c8af0a300 <php_printf>, write_function = 0x569c8af1e1c0 <php_output_write>, fopen_function = 0x569c8af0b0c0 <php_fopen_wrapper_for_zend>, message_handler = 0x569c8ad957db <php_message_
handler_for_zend>, get_configuration_directive = 0x569c8af0b0b0 <php_get_configuration_directive_for_zend>, ticks_function = 0x569c8af1aa70 <php_run_ticks>, on_timeout = 0x569c8af0a260 <php_on_timeout>, stream_open_function = 0x569c8af0b6d0 <php_stream_open_for_zend>, p
rintf_to_smart_string_function = 0x569c8af109f0 <php_printf_to_smart_string>, printf_to_smart_str_function = 0x569c8af10a00 <php_printf_to_smart_str>, getenv_function = 0x569c8af15540 <sapi_getenv>, resolve_path_function = 0x569c8af0b090 <php_resolve_path_for_zend>}
        zuv = {html_errors = true}
        retval = 0
        module_number = 0
        php_os = 0x569c8b09c331 "Linux"
        module = <optimized out>
#15 0x0000569c8b05ee75 in php_cgi_startup (sapi_module=<optimized out>) at ./sapi/fpm/fpm/fpm_main.c:769
No locals.
#16 0x0000569c8adb7430 in main (argc=4, argv=0x7ffe8cba9e98) at ./sapi/fpm/fpm/fpm_main.c:1747
        exit_status = 0
        cgi = 0
        c = -1
        use_extended_info = 0
        file_handle = {handle = {fp = 0x0, stream = {handle = 0x0, isatty = 1323280968, reader = 0x7ffe8cba9df0, fsizer = 0x74794ee21a4a <_dl_runtime_resolve_xsavec+122>, closer = 0x74794e0098c0}}, filename = 0x20, opened_path = 0x7ffe8cba9ec0, type = 152 '\230', primar
y_script = 158, in_list = 186, buf = 0x11c00 <error: Cannot access memory at address 0x11c00>, len = 0}
        orig_optind = 1
        orig_optarg = 0x0
        ini_entries_len = 0
        max_requests = 0
        requests = 0
        fcgi_fd = 0
        request = <optimized out>
        fpm_config = 0x7ffe8cbaaecc "/etc/php/8.1/fpm/php-fpm.conf"
        fpm_prefix = 0x0
        fpm_pid = 0x0
        test_conf = 0
        force_daemon = 0
        force_stderr = 0
        php_information = 0
        php_allow_to_run_as_root = 0
        ret = <optimized out>
        __func__ = "main"
        __orig_bailout = <optimized out>
        __bailout = <optimized out>
        __str = <optimized out>

PHP Version

PHP 8.1.8

Operating System

Debian sid

@cmb69
Copy link
Member

cmb69 commented Jul 7, 2022

Apparently, hardened malloc is a fallible memory allocator (i.e. it may return NULL on failure). The php-src codebase is not really suitable for this, since it expects an infallible memory allocator (i.e. it may never return NULL on failure, but rather bails out in that case), so that there are usually no NULL checks.

As such, I don't think it's worth exploring what's happening here.

@nikic
Copy link
Member

nikic commented Jul 9, 2022

@cmb69 Only the ZMM allocator is infallible, we should handle a fallible system allocator (which I assume is what is being replaced here).

@cmb69
Copy link
Member

cmb69 commented Jul 9, 2022

Ah, that would indeed be a very different scenario (I was assuming USE_ZEND_ALLOC=0).

@cgzones, can you please clarify your use case?

@cgzones
Copy link
Author

cgzones commented Jul 11, 2022

I used the standard Debian packaging for 8.1 with the source from 8.1.8, set memory_limit to -1 and added the the allocator library to /etc/ld.so.preload.

@cgzones
Copy link
Author

cgzones commented Mar 30, 2023

Duplicate of #10670

@cgzones cgzones closed this as completed Mar 30, 2023
@q9HugW
Copy link

q9HugW commented Feb 7, 2024

The same issue happens on PHP8.2 too. Please help!

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

No branches or pull requests

4 participants