Skip to content

Segfault on PHP8.3 with class type as a method parameter due to memory corruption #529

Open
@gnat42

Description

@gnat42

Hello,

We have an extension we've used for multiple years that is built against php-cpp. Recently we're looking at upgrading to php 8.3. We recompiled php-cpp and our extension and it all compiled cleanly. However php segfaults on startup. I've dug into the issue and have narrowed it down - however I've not been able to find the root cause. I'll include a full stacktrace at the end.

I narrowed it down to the following:

pdfWriter.method<&PdfWriter::writeImageToPage>("writeImageToPage", Php::Public, {
    Php::ByVal("page",Php::Type::Numeric),
    Php::ByVal("image","PDF\\PdfImage") //<--- This is the problem
});

When I exclude these lines everything starts up fine.

I tried to create a simple reproducer by copying one of the Examples from PHP-CPP and creating a simple NamespacedObject but it didn't crash no matter what I did.

I copied over my pdfWriter object from my extension to the new Examples (commenting out a bunch of implementation code) Changing the PDF\\PdfImage to

  • NonExisting\\Vendor\\NamespacedObject <-- Doesn't exist
  • Vendor\\NamespacedObject <-- Simple php-cpp class with a few getters/constructor __toString etc.
  • ArrayObject <-- part of PHP

PHP doesn't crash on startup for any of those three situations but continues to crash if I provide PDF\\PdfImage

Here's the stack trace deep in PHP functions/macros.

#0  zend_alloc_ce_cache (type_name=type_name@entry=0x7fffe3d721c1) at /usr/src/debug/php-8.3.6-1.fc40.x86_64/Zend/zend.c:2004
#1  0x0000555555833a37 in zend_normalize_internal_type (type=0x555556169b38) at /usr/src/debug/php-8.3.6-1.fc40.x86_64/Zend/zend_API.c:2781
#2  zend_register_functions (scope=scope@entry=0x555556168a70, functions=0x555556168920, function_table=function_table@entry=0x555556168ab0, type=<optimized out>)
    at /usr/src/debug/php-8.3.6-1.fc40.x86_64/Zend/zend_API.c:3029
#3  0x0000555555834029 in do_register_internal_class (orig_class_entry=0x7fffffffbd90, ce_flags=<optimized out>) at /usr/src/debug/php-8.3.6-1.fc40.x86_64/Zend/zend_API.c:3323
#4  0x00007fffe3ced251 in Php::ClassImpl::initialize(Php::ClassBase*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /lib64/libphpcpp.so.2.4
#5  0x00007fffe3cf4bb2 in Php::ExtensionImpl::initialize(int)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}::operator()(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) const () from /lib64/libphpcpp.so.2.4
#6  0x00007fffe3cf5cef in void std::__invoke_impl<void, Php::ExtensionImpl::initialize(int)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&>(std::__invoke_other, Php::ExtensionImpl::initialize(int)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) () from /lib64/libphpcpp.so.2.4
#7  0x00007fffe3cf59e8 in std::enable_if<std::is_void<void>::value, void>::type std::__invoke_r<void, Php::ExtensionImpl::initialize(int)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&>(Php::ExtensionImpl::initialize(int)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) () from /lib64/libphpcpp.so.2.4
#8  0x00007fffe3cf5596 in std::_Function_handler<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&), Php::ExtensionImpl::initialize(int):
--Type <RET> for more, q to quit, c to continue without paging--
:{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}>::_M_invoke(std::_Any_data const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) () from /lib64/libphpcpp.so.2.4
#9  0x00007fffe3d0137d in std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)>::operator()(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) const () from /lib64/libphpcpp.so.2.4
#10 0x00007fffe3cff519 in Php::Namespace::classes(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)> const&)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}::operator()(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) const () from /lib64/libphpcpp.so.2.4
#11 0x00007fffe3d00717 in void std::__invoke_impl<void, Php::Namespace::classes(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)> const&)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&>(std::__invoke_other, Php::Namespace::classes(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)> const&)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) () from /lib64/libphpcpp.so.2.4
#12 0x00007fffe3d00304 in std::enable_if<std::is_void<void>::value, void>::type std::__invoke_r<void, Php::Namespace::classes(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)> const&)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&>(Php::Namespace::classes(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)> const&)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) () from /lib64/libphpcpp.so.2.4
#13 0x00007fffe3cffe57 in std::_Function_handler<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&), Php::Namespace::classes(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)> const&)::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)#1}>::_M_invoke(std::_Any_data const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) ()
   from /lib64/libphpcpp.so.2.4
#14 0x00007fffe3d0137d in std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)>::operator()(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&) const () from /lib64/libphpcpp.so.2.4
#15 0x00007fffe3cff66c in Php::Namespace::classes(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)> const&) ()
   from /lib64/libphpcpp.so.2.4
#16 0x00007fffe3cff73b in Php::Namespace::classes(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Php::ClassBase&)> const&) ()
   from /lib64/libphpcpp.so.2.4
#17 0x00007fffe3cf4de1 in Php::ExtensionImpl::initialize(int) () from /lib64/libphpcpp.so.2.4
#18 0x00007fffe3cf43de in Php::ExtensionImpl::processStartup(int, int) () from /lib64/libphpcpp.so.2.4
#19 0x00005555558322a3 in zend_startup_module_ex (module=0x555555f37d30) at /usr/src/debug/php-8.3.6-1.fc40.x86_64/Zend/zend_API.c:2312
#20 0x0000555555832350 in zend_startup_module_zval (zv=<optimized out>) at /usr/src/debug/php-8.3.6-1.fc40.x86_64/Zend/zend_API.c:2327
#21 0x00005555558415ab in zend_hash_apply (ht=ht@entry=0x555555e08c20 <module_registry>, apply_func=apply_func@entry=0x555555832340 <zend_startup_module_zval>)
    at /usr/src/debug/php-8.3.6-1.fc40.x86_64/Zend/zend_hash.c:2086
#22 0x00005555558326bb in zend_startup_modules () at /usr/src/debug/php-8.3.6-1.fc40.x86_64/Zend/zend_API.c:2450
#23 0x00005555557bdb32 in php_module_startup (sf=<optimized out>, additional_module=0x0) at /usr/src/debug/php-8.3.6-1.fc40.x86_64/main/main.c:2225
#24 0x0000555555649db3 in main (argc=1, argv=0x555555e10a60) at /usr/src/debug/php-8.3.6-1.fc40.x86_64/sapi/cli/php_cli.c:1307

Any pointers would be appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions