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?
madcoder@gmail.com wrote: > What more can I do to debug this problem? > Well, I've posted a bug to PHP about their using deprecated LDAP code, but it was basically bounced with "mind your own business" or sort of (and this __IS__ my own business, by the way :). You could try rebuilding PHP's LDAP stuff defining -DLDAP_DEPRECATED=1 and see what happens. I've seen similar problems with AMD64 when functions got linked without a prototype, and ldap_get_values does not have a prototype in ldap.h unless the above is defined. p. Ing. Pierangelo Masarati OpenLDAP Core Team SysNet s.n.c. Via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ------------------------------------------ Office: +39.02.23998309 Mobile: +39.333.4963172 Email: pierangelo.masarati@sys-net.it ------------------------------------------
madcoder@gmail.com wrote: ... You know, what makes me mad about PHP is that it internally uses something comparable to bervals, since the abstract type they use to wrap strings takes care of the length of the string itself; but in the LDAP extension, ldap_get_values() is used everywhere, and then strlen is run to compute the length of the values! Why on earth don't they get ldap_get_values_len() should be used instead? Somehow it got hardwired in people's brain that ldap_get_values_len() is only good for "binary" (that is, non-printable) stuff, and not for strings as well! p. Ing. Pierangelo Masarati OpenLDAP Core Team SysNet s.n.c. Via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it ------------------------------------------ Office: +39.02.23998309 Mobile: +39.333.4963172 Email: pierangelo.masarati@sys-net.it ------------------------------------------
changed notes
changed notes changed state Open to Feedback
At 06:12 PM 10/1/2006, ando@sys-net.it wrote: >madcoder@gmail.com wrote: >... >You know, what makes me mad about PHP is that it internally uses >something comparable to bervals, since the abstract type they use to >wrap strings takes care of the length of the string itself; but in the >LDAP extension, ldap_get_values() is used everywhere, and then strlen is >run to compute the length of the values! Why on earth don't they get >ldap_get_values_len() should be used instead? Somehow it got hardwired >in people's brain that ldap_get_values_len() is only good for "binary" >(that is, non-printable) stuff, and not for strings as well! Folks also tend to forget that U+0000 is a valid Unicode character, as is ASCII 0... but I digress. Kurt
changed notes changed state Feedback to Closed moved from Incoming to Build
moved from Build to Archive.Build
PHP needs to build with -DLDAP_DEPRECATED=1 see ITS#4168