[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#4690) segfault in ldap_count_values() with PHP



Full_Name: Joe H
Version: 2.3.24
OS: gentoo linux (2.6.17) on amd64 Athlon X2
URL: http://bugs.php.net/bug.php?id=38819
Submission from: (NULL) (70.245.125.224)


I'm not certain yet whether this is a bug in openldap, or in PHP, but my bug
report with PHP has stalled, so I am hoping that cross-posting it here might
garnish some further insight into the problem.

The PHP bug report should explain the segfault I'm experiencing, and where the
segfault occurs.  It can be found at http://bugs.php.net/bug.php?id=38819

The segfault occurs in libraries/libldap/getvalues.c, in the ldap_count_values()
function.  The value for vals that is passed to the function cannot be read for
some reason.  At first I thought this might be a PHP problem, since the
ldapsearch utility works fine performing the same search.  However, it should
also be mentioned that the value that is sent to ldap_get_values, is a value
returned directly from ldap_get_values():

> ldap_value = ldap_get_values(ldap, ldap_result_entry, attribute);
> num_values = ldap_count_values(ldap_value);

While in ldap_count_values(), the backtrace shows that the segfault occurs
during the first iteration of the for() loop:

> Program received signal SIGSEGV, Segmentation fault.
> 0x00002b2871ad210b in ldap_count_values (vals=0x55a170c0) at getvalues.c:152
> 152             for ( i = 0; vals[i] != NULL; i++ )

Further investigating the problem shows:

> (gdb) p i
> $1 = 0
> (gdb) p vals
> $2 = (char **) 0x55a170c0
> (gdb) p vals[0]
> Cannot access memory at address 0x55a170c0

The memory address changes obviously, but the segfault always occurs at that
point.

In PHP's ldap_get_entries() function, ldap_values is defined as:

> char **ldap_value;

which is the data type expected by ldap_count_entries().  Fetching the entry
reference itself, or counting the number of entries, does not cause the segfault
-- only when getting values from the entry.  For example, PHP's
ldap_first_entry($result) works fine (as well as iterating over the entries
using ldap_next_entry()), but trying to read any of the values within the entry
will cause the segfault.

Again, the fact that it works fine with ldapsearch, but segfaults in PHP, lead
me to believe that it would be a PHP problem, but looking more into the source
code of both applications makes me lean more and more to some obscure problem in
OpenLDAP's code.  The value of 'vals' is declared and returned from this
function:

> char **
> ldap_get_values( LDAP *ld, LDAPMessage *entry, LDAP_CONST char *target )
> {
>>...
>         char            **vals;
>>...
>         if ( (res = ber_scanf( &ber, "[v]", &vals )) == LBER_ERROR ) {
>                 ld->ld_errno = LDAP_DECODING_ERROR;
>                 return( NULL );
>         }
>         return( vals );

The return value of ber_scanf is 4, but I haven't investigated what that value
indicates (it is obviously not LBER_ERROR).  In any case, that value of 'vals'
is allocated inside OpenLDAP's code, and that makes me believe that it is not a
problem with PHP's code.  The same test script functions properly on a similar
32-bit system (as similar as 32- and 64-bit systems can be).

What more can I do to debug this problem?