Issue 2825 - segfault in ldap_back_search() with ENABLE_REWRITE
Summary: segfault in ldap_back_search() with ENABLE_REWRITE
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-11-12 16:17 UTC by ftr@highstreetnetworks.com
Modified: 2014-08-01 21:06 UTC (History)
0 users

See Also:


Attachments
hsn1.patch (925 bytes, text/plain)
2003-11-13 14:36 UTC, ftr@highstreetnetworks.com
Details

Note You need to log in before you can comment on or make changes to this issue.
Description ftr@highstreetnetworks.com 2003-11-12 16:17:32 UTC
Full_Name: Tom Riddle
Version: 2.1.22
OS: Fedora Core 1.0
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (216.204.182.62)



ldap_back_search() does not handle the case where base == NULL:

#ifdef ENABLE_REWRITE
        switch ( rewrite_session( li->rwinfo, "searchBase",
                                base->bv_val, conn, &mbase.bv_val ) ) {
        case REWRITE_REGEXEC_OK:
                if ( mbase.bv_val == NULL ) {
                        mbase = *base;
                }
#ifdef NEW_LOGGING
                LDAP_LOG( BACK_LDAP, DETAIL1,
                        "[rw] searchBase: \"%s\" -> \"%s\"\n",
                        base->bv_val, mbase.bv_val, 0 );
#else /* !NEW_LOGGING */
                Debug( LDAP_DEBUG_ARGS, "rw> searchBase: \"%s\" -> \"%s\"\n%s",
                                base->bv_val, mbase.bv_val, "" );
#endif /* !NEW_LOGGING */

Comment 1 ando@openldap.org 2003-11-13 12:21:43 UTC
I assumed "base" would always be set; however,
code has been completely reworked in HEAD.
2.1.X will need a dedicated fix, I'll take care
of it asap.

Thanks, p.


> Full_Name: Tom Riddle
> Version: 2.1.22
> OS: Fedora Core 1.0
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (216.204.182.62)
>
>
>
> ldap_back_search() does not handle the case where base == NULL:
>
> #ifdef ENABLE_REWRITE
>         switch ( rewrite_session( li->rwinfo, "searchBase",
>                                 base->bv_val, conn, &mbase.bv_val ) ) {
>         case REWRITE_REGEXEC_OK:
>                 if ( mbase.bv_val == NULL ) {
>                         mbase = *base;
>                 }
> #ifdef NEW_LOGGING
>                 LDAP_LOG( BACK_LDAP, DETAIL1,
>                         "[rw] searchBase: \"%s\" -> \"%s\"\n",
>                         base->bv_val, mbase.bv_val, 0 );
> #else /* !NEW_LOGGING */
>                 Debug( LDAP_DEBUG_ARGS, "rw> searchBase: \"%s\" ->
> \"%s\"\n%s",
>                                 base->bv_val, mbase.bv_val, "" );
> #endif /* !NEW_LOGGING */


-- 
Pierangelo Masarati
mailto:pierangelo.masarati@sys-net.it


Comment 2 ftr@highstreetnetworks.com 2003-11-13 14:36:49 UTC
Pierangelo Masarati wrote:

>I assumed "base" would always be set; however,
>
slap_sasl_match(), slap_sasl2dn() and two places in sasl.c call it 
explicitly with NULL:
                                                              vvvvv
        (*be->be_search)( be, conn, &op, NULL, &dn,
                scope, LDAP_DEREF_NEVER, 1, 0,
                filter, NULL, NULL, 1 );

I tried applying the attached patch, but there are many other places 
further down that make this same assumption.

-- 
Tom Riddle
HighStreet Networks
www.highstreetnetworks.com

Comment 3 ando@openldap.org 2003-11-13 18:09:40 UTC
I suggest this patch for OPENLDAP_REL_ENG_2_1 and next 2.1 release.

ftp://ftp.openldap.org/incoming/its-2825.patch

Ando.
Comment 4 ftr@highstreetnetworks.com 2003-11-13 18:24:22 UTC
Pierangelo Masarati wrote:

>I suggest this patch for OPENLDAP_REL_ENG_2_1 and next 2.1 release.
>
>ftp://ftp.openldap.org/incoming/its-2825.patch
>
>Ando.
>  
>
Why do you say that it should not happen ??
Is it not allowed to do SASL bind on subordinate back-ldap ?  Am I doing 
something wrong ?
What about filterstr ? it too is passed as NULL by slap_sasl2dn() and 
derefenenced unconditionally.

-- 
Tom Riddle
HighStreet Networks
www.highstreetnetworks.com


Comment 5 Howard Chu 2003-11-13 19:21:09 UTC
Looks like the sasl code assumed only nbase was ever needed by the backends.
The fix is to provide a non-NULL base in sasl.c. I'll take care of this.

  -- Howard Chu
  Chief Architect, Symas Corp.       Director, Highland Sun
  http://www.symas.com               http://highlandsun.com/hyc
  Symas: Premier OpenSource Development and Support

> -----Original Message-----
> From: owner-openldap-bugs@OpenLDAP.org
> [mailto:owner-openldap-bugs@OpenLDAP.org]On Behalf Of
> ftr@highstreetnetworks.com
> Sent: Thursday, November 13, 2003 6:34 AM
> To: openldap-its@OpenLDAP.org
> Subject: Re: segfault in ldap_back_search() with ENABLE_REWRITE
> (ITS#2825)
>
>
> This is a multi-part message in MIME format.
> --------------040507020600070408090206
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
> Content-Transfer-Encoding: 7bit
>
> Pierangelo Masarati wrote:
>
> >I assumed "base" would always be set; however,
> >
> slap_sasl_match(), slap_sasl2dn() and two places in sasl.c call it
> explicitly with NULL:
>                                                               vvvvv
>         (*be->be_search)( be, conn, &op, NULL, &dn,
>                 scope, LDAP_DEREF_NEVER, 1, 0,
>                 filter, NULL, NULL, 1 );
>
> I tried applying the attached patch, but there are many other places
> further down that make this same assumption.
>
> --
> Tom Riddle
> HighStreet Networks
> www.highstreetnetworks.com
>
>
> --------------040507020600070408090206
> Content-Type: text/plain;
>  name="hsn1.patch"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline;
>  filename="hsn1.patch"
>
> --- openldap-2.1.22-orig/servers/slapd/back-ldap/search.c
> 2003-03-12 17:27:57.000000000 -0500
> +++ openldap-2.1.22/servers/slapd/back-ldap/search.c
> 2003-11-12 09:53:32.000000000 -0500
> @@ -157,18 +157,18 @@
>  	*/
>  #ifdef ENABLE_REWRITE
>   	switch ( rewrite_session( li->rwinfo, "searchBase",
> - 				base->bv_val, conn, &mbase.bv_val ) ) {
> + 			base ? base->bv_val : NULL, conn,
> &mbase.bv_val ) ) {
>  	case REWRITE_REGEXEC_OK:
> -		if ( mbase.bv_val == NULL ) {
> +		if ( mbase.bv_val == NULL && base) {
>  			mbase = *base;
>  		}
>  #ifdef NEW_LOGGING
>  		LDAP_LOG( BACK_LDAP, DETAIL1,
>  			"[rw] searchBase: \"%s\" -> \"%s\"\n",
> -			base->bv_val, mbase.bv_val, 0 );
> +			base ? base->bv_val : "", mbase.bv_val, 0 );
>  #else /* !NEW_LOGGING */
>  		Debug( LDAP_DEBUG_ARGS, "rw> searchBase: \"%s\"
> -> \"%s\"\n%s",
> -				base->bv_val, mbase.bv_val, "" );
> +			base ? base->bv_val : "", mbase.bv_val, "" );
>  #endif /* !NEW_LOGGING */
>  		break;
>
>
> --------------040507020600070408090206--
>

Comment 6 ando@openldap.org 2003-11-13 19:36:42 UTC
> Pierangelo Masarati wrote:
>
>>I suggest this patch for OPENLDAP_REL_ENG_2_1 and next 2.1 release.
>>
>>ftp://ftp.openldap.org/incoming/its-2825.patch
>>
>>Ando.
>>
>>
> Why do you say that it should not happen ??
> Is it not allowed to do SASL bind on subordinate back-ldap ?  Am I doing
>  something wrong ?

In my opinion, an empty DN is represented by a berval
with 0 length pointing to a "".  Everything else is wrong.
Besides, it's unclear to me what a base has to do with
sasl auth{c|z}

> What about filterstr ? it too is passed as NULL by slap_sasl2dn() and
> derefenenced unconditionally.

where?  In any case, one of the reasons of using bervals
instead of char*s was exactly to avoid having to check for
NULL pointers and calling strlen() all the times.  Now
all struct berval*s should be assert()ed, and a null
berval'ed field should be tested as bv->bv_val == NULL while
an empty one should be tested as bv->bv_len != 0.  In my
opinion, a NULL base is totally meaningless; an empty base
makes sense.

p.

-- 
Pierangelo Masarati
mailto:pierangelo.masarati@sys-net.it


Comment 7 Howard Chu 2003-11-13 20:42:38 UTC
changed notes
changed state Open to Test
moved from Incoming to Software Bugs
Comment 8 Jonghyuk Choi 2003-11-13 21:00:16 UTC
> where?  In any case, one of the reasons of using bervals
> instead of char*s was exactly to avoid having to check for
> NULL pointers and calling strlen() all the times.  Now
> all struct berval*s should be assert()ed, and a null
> berval'ed field should be tested as bv->bv_val == NULL while
> an empty one should be tested as bv->bv_len != 0.  In my
> opinion, a NULL base is totally meaningless; an empty base
> makes sense.

Ando,
Is it your point that we should change bv->bv_val == NULL 
to bv->bv_len == 0 along with the related codes sometime ?
Currently, berval library codes are also checking bv->bv_val
when it could check bv->bv_len, and there are also some 
cases where bv->bv_len is left uninitialized, making its user
codes unable to rely on bv->bv_len.
- Jong

Comment 9 ando@openldap.org 2003-11-13 21:27:47 UTC
>> where?  In any case, one of the reasons of using bervals
>> instead of char*s was exactly to avoid having to check for
>> NULL pointers and calling strlen() all the times.  Now
>> all struct berval*s should be assert()ed, and a null
>> berval'ed field should be tested as bv->bv_val == NULL while
>> an empty one should be tested as bv->bv_len != 0.  In my
>> opinion, a NULL base is totally meaningless; an empty base
>> makes sense.
>
> Ando,
> Is it your point that we should change bv->bv_val == NULL
> to bv->bv_len == 0 along with the related codes sometime ?
> Currently, berval library codes are also checking bv->bv_val
> when it could check bv->bv_len, and there are also some
> cases where bv->bv_len is left uninitialized, making its user
> codes unable to rely on bv->bv_len.
> - Jong

I wouldn't be so strict; however, the two things have different
meanings: bv_val == NULL means there is no value; bv_len == 0
means the value is empty, but it is a legal value.  So bv_len == 0
should be allowed to coexist with bv_val != NULL, e.g. in the
rootDSE, while bv_val == NULL should imply that bv_len must be
ignored.

The use of either form should be consistent with the meaning
of each berval.  For instance, a search base of { 0, NULL }
has little meaning, while a search base of { 0, "" } makes
sense.

This has nothing to do with the original posting, because
in that case the berval pointer was null; I'd consider this
occurrence undesirable, because it defeats the purpose of
using bervals as arguments.  Note that all this discussion
is outdated since the ABI change.

p.

-- 
Pierangelo Masarati
mailto:pierangelo.masarati@sys-net.it


Comment 10 Jonghyuk Choi 2003-11-13 22:12:36 UTC
I misinterpreted your previous posting.
Thanks. - Jong

> I wouldn't be so strict; however, the two things have different
> meanings: bv_val == NULL means there is no value; bv_len == 0
> means the value is empty, but it is a legal value.  So bv_len == 0
> should be allowed to coexist with bv_val != NULL, e.g. in the
> rootDSE, while bv_val == NULL should imply that bv_len must be
> ignored.
> 
> The use of either form should be consistent with the meaning
> of each berval.  For instance, a search base of { 0, NULL }
> has little meaning, while a search base of { 0, "" } makes
> sense.
> 
> This has nothing to do with the original posting, because
> in that case the berval pointer was null; I'd consider this
> occurrence undesirable, because it defeats the purpose of
> using bervals as arguments.  Note that all this discussion
> is outdated since the ABI change.
> 
> p.
> 
> -- 
> Pierangelo Masarati
> mailto:pierangelo.masarati@sys-net.it

Comment 11 Kurt Zeilenga 2003-12-01 02:51:00 UTC
changed state Test to Release
Comment 12 Kurt Zeilenga 2003-12-04 20:41:46 UTC
changed state Release to Closed
Comment 13 Howard Chu 2006-06-11 08:47:01 UTC
moved from Software Bugs to Archive.Software Bugs
Comment 14 OpenLDAP project 2014-08-01 21:06:29 UTC
fixed in HEAD, RE21