|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2020-02-23 12:19 UTC] isundill at gmail dot com
[2021-07-29 11:40 UTC] cmb@php.net
-Status: Open
+Status: Closed
-Assigned To:
+Assigned To: cmb
[2021-07-29 11:40 UTC] cmb@php.net
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Nov 01 13:00:01 2025 UTC |
Description: ------------ MySQL provides the concept of proxy authentication which allows it to write a server side plugin to do specific authentication of a proxy user. To make this work a client plugin is required. PHP comes with builtin authentication plugins for native auth, pam auth and sha256 auth. I tried to write a new mysqlnd auth plugin for our custom mysql authentication. The code looks something like in test-script below. The functionality works so far. The extension can be loaded, it handles the specific authentication well, but there is a segfault when php shuts down. When I run the test script in gdb, the segfault happens in this code: mysqlnd_plugin_end_apply_func (pDest=<optimized out>) at /home/tmueller/dev/php-5.6.24/ext/mysqlnd/mysqlnd_plugin.c:112 112 if (plugin_header->m.plugin_shutdown) { (gdb) bt #0 mysqlnd_plugin_end_apply_func (pDest=<optimized out>) at /home/tmueller/dev/php-5.6.24/ext/mysqlnd/mysqlnd_plugin.c:112 When I set a breakpoint on that location, there is a segfault when accessing member "m" of "plugin_header" struct. This happens because php unloads my extension before unloading the mysqlnd extension and so mysqlnd accesses a pointer which points to something that is not there anymore. When I set a breakpoint, the situation is like that: Breakpoint 1, mysqlnd_plugin_end_apply_func (pDest=<optimized out>) at /home/tmueller/dev/php-5.6.24/ext/mysqlnd/mysqlnd_plugin.c:112 112 if (plugin_header->m.plugin_shutdown) { (gdb) p plugin_header $9 = (struct st_mysqlnd_plugin_header *) 0x7ffff642b080 (gdb) p plugin_header->m Cannot access memory at address 0x7ffff642b0c0 When I call "info sharedlibrary" in gdb in PHP_MINIT_FUNCTION of my extension, the shared object is loaded: Breakpoint 1, zm_activate_wtauth (type=1, module_number=29) at /home/tmueller/dev/php-ext-wtauth/wtauth.c:111 warning: Source file is more recent than executable. 111 return SUCCESS; (gdb) info sharedlibrary From To Syms Read Shared Object Library 0x00007ffff7ddaae0 0x00007ffff7df5490 Yes /lib64/ld-linux-x86-64.so.2 0x00007ffff7bc2ad0 0x00007ffff7bd1eb9 Yes /lib/x86_64-linux-gnu/libresolv.so.2 0x00007ffff78be610 0x00007ffff792d056 Yes /lib/x86_64-linux-gnu/libm.so.6 0x00007ffff76b5ed0 0x00007ffff76b69ce Yes /lib/x86_64-linux-gnu/libdl.so.2 0x00007ffff737b9d0 0x00007ffff746249e Yes (*) /usr/lib/x86_64-linux-gnu/libxml2.so.2 0x00007ffff6fa8520 0x00007ffff70ed183 Yes /lib/x86_64-linux-gnu/libc.so.6 0x00007ffff6d71e00 0x00007ffff6d81bf8 Yes (*) /lib/x86_64-linux-gnu/libz.so.1 0x00007ffff6b500d0 0x00007ffff6b6424d Yes (*) /lib/x86_64-linux-gnu/liblzma.so.5 0x00007ffff622a900 0x00007ffff622aa70 Yes /home/tmueller/test-root/lib/php/extensions/no-debug-non-zts-20131226/wtauth.so On line 112 of mysqlnd_plugin.c in mysqlnd_plugin_end_apply_func it is not loaded anymore warning: Temporarily disabling breakpoints for unloaded shared library "/home/tmueller/test-root/lib/php/extensions/no-debug-non-zts-20131226/wtauth.so" Breakpoint 2, mysqlnd_plugin_end_apply_func (pDest=<optimized out>) at /home/tmueller/dev/php-5.6.24/ext/mysqlnd/mysqlnd_plugin.c:112 112 if (plugin_header->m.plugin_shutdown) { (gdb) info sharedlibrary From To Syms Read Shared Object Library 0x00007ffff7ddaae0 0x00007ffff7df5490 Yes /lib64/ld-linux-x86-64.so.2 0x00007ffff7bc2ad0 0x00007ffff7bd1eb9 Yes /lib/x86_64-linux-gnu/libresolv.so.2 0x00007ffff78be610 0x00007ffff792d056 Yes /lib/x86_64-linux-gnu/libm.so.6 0x00007ffff76b5ed0 0x00007ffff76b69ce Yes /lib/x86_64-linux-gnu/libdl.so.2 0x00007ffff737b9d0 0x00007ffff746249e Yes (*) /usr/lib/x86_64-linux-gnu/libxml2.so.2 0x00007ffff6fa8520 0x00007ffff70ed183 Yes /lib/x86_64-linux-gnu/libc.so.6 0x00007ffff6d71e00 0x00007ffff6d81bf8 Yes (*) /lib/x86_64-linux-gnu/libz.so.1 0x00007ffff6b500d0 0x00007ffff6b6424d Yes (*) /lib/x86_64-linux-gnu/liblzma.so.5 In our opinion there are two ways to solve the problem: 1) Unregister the plugin in PHP_MSHUTDOWN_FUNCTION method of the extension This solution currently is not possible because the mysqlnd_plugin_end_apply_func function does not appear in a header file and can not be used by our extension. 2) Load mysqlnd code before our extension but unload our extension after unloading mysqlnd This is to my knowledge not possible because php always unloads the extensions in reverse order as they were loaded. Test script: --------------- static zend_uchar * mysqlnd_test_authorization_get_auth_data(struct st_mysqlnd_authentication_plugin * self, size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, const MYSQLND_OPTIONS * const options, const MYSQLND_NET_OPTIONS * const net_options, unsigned long mysql_flags TSRMLS_DC) { // stuff her } static struct st_mysqlnd_authentication_plugin mysqlnd_test_authorization_plugin = { { MYSQLND_PLUGIN_API_VERSION, "auth_plugin_test_authorization", MYSQLND_VERSION_ID, MYSQLND_VERSION, "PHP License 3.01", "Author", { NULL, /* no statistics , will be filled later if there are some */ NULL, /* no statistics */ }, { NULL } }, {/* methods */ mysqlnd_test_authorization_get_auth_data } }; void test_auth_register_authentication_plugins(TSRMLS_D) { TSRMLS_FETCH(); mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_test_authorization_plugin.plugin_header TSRMLS_CC); } PHP_MINIT_FUNCTION(testauth) { test_auth_register_authentication_plugins(TSRMLS_C); return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(testauth) { // What to do here return SUCCESS; } PHP_RINIT_FUNCTION(testauth) { return SUCCESS; }