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

Re: (ITS#3388) Seg11 when used with pam_ldap under dtlogin

Hi, Howard,

Thanks for your time...

I'm 100% certain this isn't an lber mixup, as i am giving explicit 
paths to the static objects when i link.  When using the dynamic 
libraries, ldd gives me openldap's libraries.  Here's my LIBS line from 
pam_ldap's Makefile:

	LIBS = ../openldap-2.2.18/libraries/liblber/.libs/liblber.a \
		../openldap-2.2.18/libraries/libldap/.libs/libldap.a \
		-lsocket -lnsl -lcrypt -lresolv -lpam -ldl -lssl -lcrypto

To confirm, 'pldd <pid of dtlogin>' does not list ANY ldap-related 
libraries, system or openldap.  This is to be expected, since they're 
staticly linked.

Also, Solaris8 has no liblber that I can find -- the only mentions i 
have of it are in openldap's installation prefix (/usr/local).

In order to ensure this isn't a conflict between the built-in LDAP 
header files, i have renamed /usr/include/ldap.h and lber.h out of the 
way.  Now it should only ever find openldap's ldap.h and lber.h.  Then 
I rebuilt openldap and pam_ldap, and am still seeing the problem.

While I can't be certain it's openldap (or that it is pam_ldap), i'm 
running out of other possibilities.

To me (and i admit i don't know the code base very intimately), it 
looks like ldap_build_search_req() allocates, zeros, then tries to use 
BerEntity* members (in particular ber_ptr), without exposing any of 
those details to pam_ldap.  I spent most of yesterday with gdb on this 
issue, and I couldn't figure out where ber_ptr was getting set.  Can 
you point me to the line of code which sets ber_ptr for this code path? 
  That would conclusively indicate that it isn't openldap.

In the future, when i file bugs against openldap, what do i need to 
bring to the table?  What can i research further?  I thought i had 
gathered everything -- i have stack traces, i've narrowed it down to 
the exact line, i've told you what the problem is.  I'd send you a 
patch if i knew how ber_ptr was supposed to be set... Is there 
something more I can help with?


- joel

On Nov 10, 2004, at 7:44 AM, Howard Chu wrote:

> As pam_ldap is not a component of OpenLDAP software, this bug report 
> doesn't belong here.
> In general, problems on Solaris result from the Solaris native 
> binaries being linked against Sun's libldap/liblber and thus the wrong 
> liblber getting used when OpenLDAP's libldap is invoked. Resolving 
> this library conflict is just a matter of using the right linker flags 
> when building pam_ldap/nss_ldap. With that said, I am closing this 
> ITS.
> jdb@force10networks.com wrote:
>> Full_Name: Joel Boutros
>> Version: 2.2.18
>> OS: Solaris8
>> URL: Submission from: (NULL) (
>> I have reproduced this problem with 2.2.18, 2.2.17, and 2.0.107(?).
>> I'm using pam_ldap 1.76, linked against the static version of 
>> OpenLDAP 2.2.18,
>> on Solaris8 (also happens with dynamicly linked version, but my 
>> version of gdb
>> can't get symbols out of liblber, so i switched to static).  I am 
>> getting
>> crashes under dtlogin.  The call-stack (as far as OpenLDAP sees) is 
>> as follows
>> (some strings have been replaced by XXX for security reasons.  the 
>> addresses
>> remain the same):
>> Program received signal SIGSEGV, Segmentation fault.
>> 0xfeda0620 in memcpy () from 
>> /usr/platform/SUNW,Ultra-60/lib/libc_psr.so.1
>> (gdb) bt
>> #0  0xfeda0620 in memcpy () from 
>> /usr/platform/SUNW,Ultra-60/lib/libc_psr.so.1
>> #1  0xfdf2b4b8 in ber_write (ber=0xfe122d98, buf=0xffbee4b3 "\002", 
>> len=1,    nosos=0) at io.c:97
>> #2  0xfdf29f8c in ber_put_tag (ber=0xfe122d98, tag=0, nosos=0) at 
>> encode.c:97
>> #3  0xfdf2a1dc in ber_put_int_or_enum (ber=0xfe122d98, num=1, tag=2)
>>    at encode.c:225
>> #4  0xfdf2b050 in ber_printf (ber=0xfe122d98, fmt=0xfdfcbb81 
>> "it{seeiib")
>>    at encode.c:723
>> #5  0xfdf31c98 in ldap_build_search_req (ld=0x619a8,    base=0x5f8c8 
>> "CN=XXX,DC=XXX,DC=com", scope=2,    filter=0xffbeebb0
>> "(&(objectclass=User)(objectclass=User)(sAMAccountName=XXX))", 
>> attrs=0x0,
>> attrsonly=0, sctrls=0x0, cctrls=0x0, timelimit=-1,    sizelimit=-1, 
>> idp=0x2) at search.c:278
>> #6  0xfdf31ba8 in ldap_search (ld=0x619a8,    base=0x5f8c8 
>> "CN=XXX,DC=XXX,DC=com", scope=2,    filter=0xffbeebb0
>> "(&(objectclass=User)(objectclass=User)(sAMAccountName=XXX))", 
>> attrs=0x0,
>> attrsonly=0) at search.c:192
>> #7  0xfdf31e38 in ldap_search_s (ld=0x619a8,    base=0x5f8c8 
>> "CN=XXX,DC=XXX,DC=com", scope=2,    filter=0xffbeebb0
>> "(&(objectclass=User)(objectclass=User)(sAMAccountName=XXX))", 
>> attrs=0x0,
>> attrsonly=0, res=0xffbee798) at search.c:360
>> #8  0xfdf253dc in _get_user_info (session=0xfe212950, user=0xfe302ba0 
>> "XXX")
>>    at pam_ldap.c:2476
>> #9  0xfdf25ac4 in _do_authentication (pamh=0x52a58, 
>> session=0xfe212950,    user=0xfe302ba0 "XXX", password=0xfe302bd8 
>> "XXX") at pam_ldap.c:2768
>> #10 0xfdf26488 in pam_sm_authenticate (pamh=0x52a58, flags=0, argc=0, 
>> argv=0x0)
>>    at pam_ldap.c:3203
>> ...
>> (gdb) fr 1
>> #1  0xfdf2b4b8 in ber_write (ber=0xfe122d98, buf=0xffbee4b3 "\002", 
>> len=1,    nosos=0) at io.c:97
>> 97                      AC_MEMCPY( ber->ber_sos->sos_ptr, buf, 
>> (size_t)len );
>> (gdb) p *ber
>> $1 = {ber_opts = {lbo_valid = 2, lbo_options = 1, lbo_debug = 0,    
>> lbo_meminuse = 0}, ber_tag = 4294967295, ber_len = 0, ber_usertag = 
>> 0,  ber_buf = 0xfe122d98 "", ber_ptr = 0x0,  ber_end = 0x30 <Address 
>> 0x30 out of bounds>, ber_sos = 0xfe122db0,  ber_rwptr = 0x6 <Address 
>> 0x6 out of bounds>, ber_memctx = 0x0}
>> (gdb) p *ber->ber_sos
>> $2 = {sos_ber = 0xfe122d98, sos_clen = 0, sos_tag = 48,  sos_first = 
>> 0xfe122db0 "?\022-\230",  sos_ptr = 0x6 <Address 0x6 out of bounds>, 
>> sos_next = 0x0}
>>> From what I can tell, it looks like when ber is allocated in
>> ldap_build_search_req, it is zeroed out (calloc()), but then 
>> ber->ber_ptr is
>> reset, and at openldap-2.2.18/libraries/liblber/encode.c:465, it uses
>> new->sos_first (which is derived from ber->ber_ptr) in some pointer 
>> arithmetic,
>> producing 0x06 as a result (new->sos_ptr = NULL + 
>> ber_calc_taglen(tag) + 5). Then new->sos_ptr is later used in a 
>> memcpy(), causing the crash.
>> Interestingly enough, I'm not seeing problems like this under other 
>> pam-enabled
>> applications.  But, it looks like the behavior is the same in both 
>> cases -- it
>> is always dereferencing this pointer.  So it seems like dtlogin's 
>> environment is
>> helping to expose a latent problem?
>> Any ideas how to fix this?  I can't figure out how ber->ber_ptr 
>> should be at
>> initialized.  I tried setting it to ber->ber_val, but it crashes in 
>> other ways
>> later, so that wasn't right...
>> If you need any further data, please let me know.
>> Thanks!
>> - joel
> -- 
>  -- Howard Chu
>  Chief Architect, Symas Corp.       Director, Highland Sun
>  http://www.symas.com               http://highlandsun.com/hyc
>  Symas: Premier OpenSource Development and Support