Kurt, great work!
I just tested this on maverick, and indeed, this produces the segfault, but it does it no matter what, if you skip any of the string parameters:
clint@ubuntu:~$ php -r 'mssql_connect("");' Segmentation fault
In fact, this happens with a vanilla compiled PHP 5.3.3 as well:
This logic in php_mssql.c is actually pretty wrong:
char *host = NULL, *user = NULL, *passwd = NULL; int host_len, user_len, passwd_len; zend_bool new_link = 0; char *hashed_details; int hashed_details_length; mssql_link mssql, *mssql_ptr; char buffer[40];
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sssb", &host, &host_len, &user, &user_len, &passwd, &passwd_len, &new_link) == FAILURE) { return; }
/* Limit strings to 255 chars to prevent overflow issues in underlying libraries */ if(host_len>255) { host[255] = '\0'; } if(user_len>255) { user[255] = '\0'; } if(passwd_len>255) { passwd[255] = '\0'; }
zend_parse_args() won't modify the length or content if the variables aren't passed, so its trying to dereference a NULL pointer there, as host_len is still set to whatever random value might have been given to it.
I forwarded this upstream,
http://bugs.php.net/bug.php?id=52843
I included a patch there. Will submit a merge proposal as well.
Kurt, great work!
I just tested this on maverick, and indeed, this produces the segfault, but it does it no matter what, if you skip any of the string parameters:
clint@ubuntu:~$ php -r 'mssql_ connect( "");'
Segmentation fault
In fact, this happens with a vanilla compiled PHP 5.3.3 as well:
This logic in php_mssql.c is actually pretty wrong:
char *host = NULL, *user = NULL, *passwd = NULL; details_ length;
int host_len, user_len, passwd_len;
zend_bool new_link = 0;
char *hashed_details;
int hashed_
mssql_link mssql, *mssql_ptr;
char buffer[40];
if (zend_parse_ parameters( ZEND_NUM_ ARGS() TSRMLS_CC, "|sssb", &host, &host_len, &user, &user_len, &passwd, &passwd_len, &new_link) == FAILURE) {
return;
}
/* Limit strings to 255 chars to prevent overflow issues in underlying libraries */
if(host_ len>255) {
host[ 255] = '\0';
if(user_ len>255) {
user[ 255] = '\0';
if(passwd_ len>255) {
passwd[ 255] = '\0';
}
}
}
zend_parse_args() won't modify the length or content if the variables aren't passed, so its trying to dereference a NULL pointer there, as host_len is still set to whatever random value might have been given to it.
I forwarded this upstream,
http:// bugs.php. net/bug. php?id= 52843
I included a patch there. Will submit a merge proposal as well.