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

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



Hi, Howard,

I've tried to put this together to make it more clear what the problem 
I'm seeing is...  This is the call tree which results in the bug.  As 
things are pushed onto the stack, I indent.  When it's done, I 
un-indent.  if something allocates, i mark it with a -->.  I've removed 
anything that isn't relevant to the problem at hand (ie, assert()s, 
error checks, unrelated assignments, etc).

If you've got alternatives or can explain why this isn't the cause of 
the crash, please!, i'm very interested.  I'd really like to get this 
problem solved, so a refutal would tell me where i should look instead. 
  As it stands, this "feels" like an OpenLDAP issue.

pam_ldap code
	ldap_search_s
		ldap_search
			ldap_build_search_req
				ldap_alloc_ber_with_options
					ber_alloc_t
						LBER_CALLOC   --> ber
						ber->valid = LBER_VALID_BERELEMENT;
						ber->ber_tag = LBER_DEFAULT;
						ber->ber_options = options;
						ber->ber_debug = ber_int_debug;
				LDAP_NEXT_MSGID
				ber_printf(ld, "{it{seeiib", ...)
					ber_start_seq
						ber_start_seqorset
							ber_mamcalloc_x  --> new
1							new->sos_first = ber->ber_ptr;
1							new->sos_ptr = new->sos_first + ber_calc_taglen(tag) + 
FOUR_BYTE_LEN;
							ber->ber_sos = new
					ber_put_int
						ber_put_int_or_enum
							ber_put_tag
								ber_write
									if ( nosos || ber->ber_sos == NULL ) {   ber->ber_sos same as 
new above, so !NULL
2									if ( ber->ber_ptr + len > ber->ber_end ) { }  ber->ber_ptr == 
0, ber->ber_end == 0
3									ber_realloc( ber, len )
									}
									AC_MEMCPY( ber->ber_ptr, buf, (size_t)len );
									ber->ber_ptr += len;



The two lines marked (1) lines are the problem, as far as i can tell.  
ber->ber_ptr is NULL.  Nothing ever set it to non-NULL after the calloc 
in ber_alloc_t.  So new->sos_first is 0, ber_calc_taglen(tag) == 1, and 
FOUR_BYTE_LEN == 5.  new->sos_ptr becomes 0x6, and then we dereference 
it in ber_write()'s memcpy (much later).

It isn't clear what the results of (2) are, but it seems likely to 
evaluate true, as ber->ber_ptr is 6, len is at least something, and 
ber->ber_end is probably (never got set to anything else).

ber->berber_realloc (3) is the only place that ber->ber_ptr can 
possibly move.  It getting moved depends on ber_memrealloc_x() 
returning moved memory.  It isn't clear how it really behaves here, 
though -- if it moves at all, ber->ber_ptr = (ber->ber_buf + 
(ber->ber_ptr - oldbuf)); when ber->ber_ptr is 0x6, and we're 
subtracting oldbuf.  We'll end up with total trash on ber->ber_ptr.  
That's if it moves.  If it doesn't, ber->ber_ptr continues to be 0x6, 
which is what i've seen in the AC_MEMCPY() call.

Maybe this problem only comes up when ber_memrealloc_x() returns a 
moved region.  This would explain why i see it under dtlogin, but don't 
usually see it otherwise.  I have verified that ber->ber_ptr is 0x6 at 
the point ber_printf() is called when debugging under a working case, 
but haven't had a lot of luck identifying why it then continues to work 
(my "working" test case involves time limits because it's under 
login(1), and i just can't get to the call quickly enough).

Again, thanks for your time, I realize i'm being more irritating at 
following this up than most people are.  I'm just firmly convinced i'm 
right, that this really is an OpenLDAP issue, as, so far, there's 
something to suggest there's a different issue at-fault.

- 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) (206.54.51.125)
>>
>>
>> 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
>