Req #72919 [NEW]: Problem when writing php extension which provides a mysql auth mehtod

From: Date: Mon, 22 Aug 2016 09:47:56 +0000
Subject: Req #72919 [NEW]: Problem when writing php extension which provides a mysql auth mehtod
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-203484@lists.php.net to get a copy of this message
From:             tobias dot mueller at hostpoint dot ch
Operating system: ALL
PHP version:      5.6.25
Package:          MySQL related
Bug Type:         Feature/Change Request
Bug description:Problem when writing php extension which provides a mysql auth mehtod

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;
}



-- 
Edit bug report at https://bugs.php.net/bug.php?id=72919&edit=1
-- 
Try a snapshot (PHP 5.4):   https://bugs.php.net/fix.php?id=72919&r=trysnapshot54
Try a snapshot (PHP 5.5):   https://bugs.php.net/fix.php?id=72919&r=trysnapshot55
Try a snapshot (trunk):     https://bugs.php.net/fix.php?id=72919&r=trysnapshottrunk
Fixed in SVN:               https://bugs.php.net/fix.php?id=72919&r=fixed
Fixed in release:           https://bugs.php.net/fix.php?id=72919&r=alreadyfixed
Need backtrace:             https://bugs.php.net/fix.php?id=72919&r=needtrace
Need Reproduce Script:      https://bugs.php.net/fix.php?id=72919&r=needscript
Try newer version:          https://bugs.php.net/fix.php?id=72919&r=oldversion
Not developer issue:        https://bugs.php.net/fix.php?id=72919&r=support
Expected behavior:          https://bugs.php.net/fix.php?id=72919&r=notwrong
Not enough info:            https://bugs.php.net/fix.php?id=72919&r=notenoughinfo
Submitted twice:            https://bugs.php.net/fix.php?id=72919&r=submittedtwice
register_globals:           https://bugs.php.net/fix.php?id=72919&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=72919&r=php4
Daylight Savings:           https://bugs.php.net/fix.php?id=72919&r=dst
IIS Stability:              https://bugs.php.net/fix.php?id=72919&r=isapi
Install GNU Sed:            https://bugs.php.net/fix.php?id=72919&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=72919&r=float
No Zend Extensions:         https://bugs.php.net/fix.php?id=72919&r=nozend
MySQL Configuration Error:  https://bugs.php.net/fix.php?id=72919&r=mysqlcfg



Thread (3 messages)

« previous php.bugs (#203484) next »