Issue 8568 - slapd SASL EXTERNAL bind getprop SSF bug; can provoke SEGFAULT
Summary: slapd SASL EXTERNAL bind getprop SSF bug; can provoke SEGFAULT
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: 2.4.44
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-01-15 21:15 UTC by william.b.clay@acm.org
Modified: 2017-06-01 22:09 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description william.b.clay@acm.org 2017-01-15 21:15:54 UTC
Full_Name: Bill Clay
Version: 2.4.44
OS: Debian/GNU Linux 7.8 (Wheezy)
URL: 
Submission from: (NULL) (79.12.44.250)


In sasl.c 2.4.44 slap_sasl_bind() the target variable for "sasl_getprop( ctx,
SASL_SSF_EXTERNAL, (void *)&ssf );" is declared "sasl_ssf_t ssf" but
sasl_getprop() needs "sasl_ssf_t *ssf".  This also necessitates adjustment of
the last argument of the corresponding sasl_setprop() later in the same proc.

In certain circumstances (e.g., two successive localhost EXTERNAL binds with on
the same LDAP connection on a Debian Linux amd64 system), this provokes a fatal
slapd SIGSEGV at sasl.c:1504 due to pointer ctx corruption (low-order 4 bytes of
ctx overwritten by the high-order 4 bytes of
&op->o_hdr->oh_conn->c_sasl_authctx.external.ssf):

(gdb) bt
#0  sasl_getprop (conn=0x7f1f00007f1f, propnum=propnum@entry=102, 
    pvalue=pvalue@entry=0x7f1faed42948) at ../../lib/common.c:1042
#1  0x000000000047105c in slap_sasl_bind (op=op@entry=0x7f1fa0002930,
rs=rs@entry=0x7f1faed42a60)
    at sasl.c:1504
#2  0x000000000043ecf7 in fe_op_bind (op=0x7f1fa0002930, rs=0x7f1faed42a60) at
bind.c:280
#3  0x000000000043e591 in do_bind (op=0x7f1fa0002930, rs=0x7f1faed42a60) at
bind.c:205
#4  0x0000000000422145 in connection_operation (ctx=ctx@entry=0x7f1faed42b90, 
    arg_v=arg_v@entry=0x7f1fa0002930) at connection.c:1158
#5  0x000000000042242e in connection_read_thread (ctx=0x7f1faed42b90,
argv=<optimized out>)
    at connection.c:1294
#6  0x00000000004dc978 in ldap_int_thread_pool_wrapper (xpool=0x124a010) at
tpool.c:696
#7  0x00007f1f5c3030a4 in start_thread () from
/lib/x86_64-linux-gnu/libpthread.so.0
#8  0x00007f1ff22f862d in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb)

Usually, there is no obvious impact; I have not been able to provoke the SIGSEGV
except with localhost LDAP connections.

The following patch seems to correct this issue. I have tested it only on a
Debian Linux amd64 system, OpenLDAP 2.4.44 build from source, running with Cyrus
SASL 2.1.25 as distributed in Debian Wheezy.

bill@fuji:/usr/local/src/openldap-2.4.44/servers/slapd$ diff sasl.c.orig sasl.c
1501c1501
< 			sasl_ssf_t ssf = 0;
---
> 			sasl_ssf_t *ssf = NULL;
1514c1514
< 				sasl_setprop( ctx, SASL_SSF_EXTERNAL, &ssf );
---
> 				sasl_setprop( ctx, SASL_SSF_EXTERNAL, ssf );
bill@fuji:/usr/local/src/openldap-2.4.44/servers/slapd$
Comment 1 Quanah Gibson-Mount 2017-01-15 23:17:11 UTC
--On Sunday, January 15, 2017 9:15 PM +0000 william.b.clay@acm.org wrote:


> The following patch seems to correct this issue. I have tested it only on
> a Debian Linux amd64 system, OpenLDAP 2.4.44 build from source, running
> with Cyrus SASL 2.1.25 as distributed in Debian Wheezy.
>
> bill@fuji:/usr/local/src/openldap-2.4.44/servers/slapd$ diff sasl.c.orig
> sasl.c 1501c1501
> < 			sasl_ssf_t ssf = 0;
> ---
>> 			sasl_ssf_t *ssf = NULL;
> 1514c1514
> < 				sasl_setprop( ctx, SASL_SSF_EXTERNAL, &ssf );
> ---
>> 				sasl_setprop( ctx, SASL_SSF_EXTERNAL, ssf );
> bill@fuji:/usr/local/src/openldap-2.4.44/servers/slapd$

Hi Bill,

Thanks very much for the report!  It looks like this was introduced in 
OpenLDAP 2.2.  It's definitely not a common case.  In the future, please 
follow the contribution guidelines documented at 
<http://www.openldap.org/devel/contributing.html>

Regards,
Quanah

--

Quanah Gibson-Mount
Product Architect
Symas Corporation
Packaged, certified, and supported LDAP solutions powered by OpenLDAP:
<http://www.symas.com>


Comment 2 Quanah Gibson-Mount 2017-01-15 23:18:50 UTC
changed notes
changed state Open to Release
moved from Incoming to Software Bugs
Comment 3 Michael Ströder 2017-01-17 07:57:13 UTC
william.b.clay@acm.org wrote:
> In certain circumstances (e.g., two successive localhost EXTERNAL binds

Just to be sure:

What do you mean with "localhost" in this context?

Really ldap://localhost or ldapi://?

SASL EXTERNAL most times only makes sense in the latter case (unless you've
configured a TLS certificate with name "localhost").

Ciao, Michael.


Comment 4 william.b.clay@acm.org 2017-01-17 09:38:13 UTC
By localhost, I simply meant running the LDAP client I am developing on 
the same host as slapd.  To test the same code on different client 
hosts, the coded test URIs always specified the server's FQDN.

The same tests over the same client code running on a different host 
than slapd never got SEGFAULTs -- which I find curious given the nature 
of that little bug. There must be some difference in OS memory 
allocation logic applied in the two cases.

I recognize EXTERNAL may not be heavily used, although it's quite useful 
in the environment I'm supporting. I was simply doing exhaustive testing 
of my client code under all combinations of transport and 
authentication.  With this bug plugged and using Cyrus SASL 2.1.26 at 
both ends (2.1.25 has a memory leak for my client), EXTERNAL runs fine 
in all cases: client local or remote; URI ldapi:// (auth on gid/uid), 
ldaps:// (auth on cert subject user DN), or ldap:// w/ startTLS (idem).

Comment 5 Michael Ströder 2017-01-17 11:35:51 UTC
william.b.clay@acm.org wrote:
> By localhost, I simply meant running the LDAP client I am developing on 
> the same host as slapd.  To test the same code on different client 
> hosts, the coded test URIs always specified the server's FQDN.

So you're using TLS client cert and SASL/EXTERNAL to a hostname (also in ther
server cert) but where the IP address of the hostname is directly routed through
127.0.0.1?

> The same tests over the same client code running on a different host 
> than slapd never got SEGFAULTs -- which I find curious given the nature 
> of that little bug. There must be some difference in OS memory 
> allocation logic applied in the two cases.

Not sure but the difference is the client IP address. If the client can reach
slapd through 127.0.0.1 the client's IP address is also 127.0.0.1 which could
make a difference in the SASL client handling. Anyone said hostname
canonicalization? Does setting sasl-host <fqdn> make a difference?

> I recognize EXTERNAL may not be heavily used, although it's quite useful 
> in the environment I'm supporting.

Actually I'm heavily using SASL/EXTERNAL in almost all my customer setups and in
Æ-DIR using either LDAPI:// with Unix Peer Credential passing or TLS with client
certs (e.g. for replication).

Therefore I appreciate every fix going into this. :-)

Ciao, Michael.

Comment 6 william.b.clay@acm.org 2017-01-18 08:10:18 UTC
> So you're using TLS client cert and SASL/EXTERNAL to a hostname (also in ther
> server cert) but where the IP address of the hostname is directly routed through
> 127.0.0.1?

The slapd log of my same-host tests confirms they in fact used the IPv4 
loopback address, 127.0.0.1, even though the bind URI specified the FQDN.

> Not sure but the difference is the client IP address. If the client can reach
> slapd through 127.0.0.1 the client's IP address is also 127.0.0.1 which could
> make a difference in the SASL client handling. Anyone said hostname
> canonicalization? Does setting sasl-host <fqdn> make a difference?

The ~/.ldaprc used by the client in these tests contained "TLS_REQCERT 
none", so a mismatch between the server's FQDN and the peer address 
actually used would not have been detected.  Another difference would be 
"ping-pong" memory allocation between client and server.  Even though 
different processes, they may allocate from the same pool.  With the 
client running on a different host in other tests, slapd would not be 
competing with other processes in a predictable, repeatable fashion 
(slapd SEGFAULTs were 100% repeatable for specific sequences of EXTERNAL 
binds, but only with client and server on the same host).

Comment 7 OpenLDAP project 2017-06-01 22:09:35 UTC
Fixed in master
Fixed in RE25
Fixed in RE24 (2.4.45)
Comment 8 Quanah Gibson-Mount 2017-06-01 22:09:35 UTC
changed notes
changed state Release to Closed