Bug 1989919

Summary: CLDAP ldap_result hangs if nobody listens on the port
Product: Red Hat Enterprise Linux 7 Reporter: Simon Pichugin <spichugi>
Component: openldapAssignee: LDAP Maintainers <ldap-maint>
Status: CLOSED ERRATA QA Contact: RHDS QE <ds-qe-bugs>
Severity: high Docs Contact:
Priority: high    
Version: 7.9CC: afarley, atikhono, bsmejkal, cbuissar, jreznik, ldap-maint, msauton, sgouvern
Target Milestone: rcKeywords: Triaged, ZStream
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: openldap-2.4.44-24.el7_9 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-08-31 09:11:21 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1973796    

Description Simon Pichugin 2021-08-04 10:45:22 UTC
This bug was initially created as a copy of Bug #1875361

I am copying this bug because: 
bz1973796 depends on the fix so we need to backport the change to RHEL 7.9.z


SSSD wants to perform multiple CLDAP pings to Active Directory in parallel. However openldap has a bug that cause a blocking i/o call when connection to the UDP port can not be established.

Upstream BZ (merged):
https://bugs.openldap.org/show_bug.cgi?id=9328

When using LDAP over UDP, calling ldap_result() hangs if there is nobody listening on the remote port.

The problem is that it calls recvfrom() twice, the first attempt returns ECONNREFUSED but this is ignored. The seconds read then blocks/timeouts/returns EAGAIN depending on the sockets settings, however we know that we will never receive any data so it should return an error. See [1]

poll([{fd=20, events=POLLIN|POLLPRI}], 1, 0) = 1 ([{fd=20, revents=POLLERR}])
recvfrom(20, 0x18dade0, 16256, 0, 0x18dad60, [128]) = -1 ECONNREFUSED (Connection refused)
recvfrom(20,  <unfinished ...>)         = ? 

[1] https://git.openldap.org/pbrezina/openldap/-/blob/master/libraries/libldap/result.c#L489

Reproducer:
$ gcc -ggdb3 -o client ./main.c -lldap
$ strace ./client
...
sendto(3, "0'\2\1\1\4\0c \4\0\n\1\0\n\1\0\2\1\0\2\1\0\1\1\0\207\vobje"..., 41, 0, {sa_family=AF_INET, sin_port=htons(3333), sin_addr=inet_addr("127.0.0.1")}, 16) = 41
poll([{fd=3, events=POLLIN|POLLPRI}], 1, 1000) = 1 ([{fd=3, revents=POLLERR}])
recvfrom(3, 0x493b10, 16256, 0, 0x493a90, [128]) = -1 ECONNREFUSED (Connection refused)
recvfrom(3, 

No LDAP server is running at localhost.

Comment 14 errata-xmlrpc 2021-08-31 09:11:21 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (openldap bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2021:3334