Bug 1699793

Summary: Perl inet_aton is not thread-safe [BaseOS]
Product: Red Hat Enterprise Linux 8 Reporter: Petr Pisar <ppisar>
Component: perl-SocketAssignee: perl-maint-list
Status: CLOSED ERRATA QA Contact: RHEL CS Apps Subsystem QE <rhel-cs-apps-subsystem-qe>
Severity: medium Docs Contact: Mariya Pershina <mpershin>
Priority: medium    
Version: 8.0CC: bnater, jorton, lkuprova, lmanasko, mkyral, pandrade, perl-maint-list, ppisar, rhel-stacks-subsystem-qe
Target Milestone: rcKeywords: Patch
Target Release: 8.0   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: perl-Socket-2.027-3.el8 Doc Type: Bug Fix
Doc Text:
.`Socket::inet_aton()` can now be used from multiple threads safely Previously, the `Socket::inet_aton()` function, used for resolving a domain name from multiple Perl threads, called the unsafe `gethostbyname()` `glibc` function. Consequently, an incorrect IPv4 address was occasionally returned, or the Perl interpreter terminated unexpectedly. With this update, the `Socket::inet_aton()` implementation has been changed to use the thread-safe `getaddrinfo()` `glibc` function instead of `gethostbyname()`. As a result, the `inet_aton()` function from Perl `Socket` module can be used from multiple threads safely.
Story Points: ---
Clone Of: 1693293
: 1699958 (view as bug list) Environment:
Last Closed: 2019-11-05 22:09:26 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Proposed fix
none
Reproducer
none
Reproducer none

Description Petr Pisar 2019-04-15 09:01:58 UTC
+++ This bug was initially created as a clone of Bug #1693293 +++

It seems inet_aton should be thread safe (see https://stackoverflow.com/questions/2319469/is-perls-inet-aton-thread-safe) so there might be a bug with RHEL7's Perl.

[...]

and indeed, adding breakpoints to gethostbyname and gethostbyname_r it shows
gethostbyname is called from a thread; should call only gethostbyname_r.

Breakpoint 1, 0x00007ffff68096a0 in gethostbyname () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff68096a0 in gethostbyname () from /lib64/libc.so.6
#1  0x00007fffef7a2363 in XS_Socket_inet_aton () from /usr/lib64/perl5/vendor_perl/auto/Socket/Socket.so
#2  0x00007ffff7b093ef in Perl_pp_entersub () from /usr/lib64/perl5/CORE/libperl.so
#3  0x00007ffff7b01b66 in Perl_runops_standard () from /usr/lib64/perl5/CORE/libperl.so
#4  0x00007ffff7a99148 in Perl_call_sv () from /usr/lib64/perl5/CORE/libperl.so
#5  0x00007fffefdbdcf9 in S_ithread_run () from /usr/lib64/perl5/vendor_perl/auto/threads/threads.so
#6  0x00007ffff6ac5dd5 in start_thread () from /lib64/libpthread.so.0
#7  0x00007ffff67eeead in clone () from /lib64/libc.so.6

[...]

--- Additional comment from Petr Pisar on 2019-03-27 16:22:18 GMT ---

Thank you for the report. I confirm I can reproduce the issue.

The inet_aton() function is provided by Socket Perl module and it indeed calls gethostbyname() that is not thread-safe:

void
inet_aton(host)
    char *  host
    CODE:
    {
    struct in_addr ip_address;
    struct hostent * phe;

    if ((*host != '\0') && inet_aton(host, &ip_address)) {
        ST(0) = sv_2mortal(newSVpvn((char *)&ip_address, sizeof(ip_address)));
        XSRETURN(1);
    }

→   phe = gethostbyname(host);
    if (phe && phe->h_addrtype == AF_INET && phe->h_length == 4) {
        ST(0) = sv_2mortal(newSVpvn((char *)phe->h_addr, phe->h_length));
        XSRETURN(1);
    }

    XSRETURN_UNDEF;
    }

As a workaround I recommend using getaddrinfo() from the same Socket module instead. It's thread safe and supports IPv6. As replacement for IO:Socket::INET I recommend IO::Socket::IP instead.

------

RHEL-8 is affected (perl-Socket-2.027-2.el8, perl-Socket-2.027-3.module+el8.1.0+2926+ce7246ad).

Comment 1 Petr Pisar 2019-04-15 09:15:16 UTC
Created attachment 1555172 [details]
Proposed fix

Comment 2 Petr Pisar 2019-04-15 11:21:21 UTC
Created attachment 1555187 [details]
Reproducer

It requires some records in /etc/hosts.

Comment 3 Petr Pisar 2019-04-15 12:13:47 UTC
Created attachment 1555192 [details]
Reproducer

Handle died threads.

Comment 13 errata-xmlrpc 2019-11-05 22:09:26 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, 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-2019:3546