Bug 1950 - sshd tries to bind over and over to ::1 for several seconds
Summary: sshd tries to bind over and over to ::1 for several seconds
Status: CLOSED WORKSFORME
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sshd (show other bugs)
Version: 5.9p1
Hardware: All All
: P2 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-12 21:47 AEDT by Arkadiusz Miśkiewicz
Modified: 2019-05-03 14:42 AEST (History)
2 users (show)

See Also:


Attachments
sshd log for that (174.20 KB, text/plain)
2011-11-12 21:47 AEDT, Arkadiusz Miśkiewicz
no flags Details
skip family if address is unavailable (EADDRNOTAVAIL) (399 bytes, text/plain)
2011-11-12 21:49 AEDT, Arkadiusz Miśkiewicz
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Arkadiusz Miśkiewicz 2011-11-12 21:47:26 AEDT
Created attachment 2105 [details]
sshd log for that

When AF_INET6 socket creation is allowed but bind()ing to ::1 is impossible then sshd loops until MAX_DISPLAYS is reached trying to bind to ::1 and then fails. This takes several seconds unfortunately which slows down login process a lot.

When such scenario can happen, so AF_INET6 socket creation is allowed but ::1 doesn't exist? This can happen in linux-vserver.org guest or on a pure Linux system with net.ipv6.conf.all.disable_ipv6 sysctl set to 1.


That how it looks under strace:

28636 10:33:49 socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 6 <0.000020>
28636 10:33:49 connect(6, {sa_family=AF_INET6, sin6_port=htons(6493), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EAD
DRNOTAVAIL (Cannot assign requested address) <0.000020>
28636 10:33:49 connect(6, {sa_family=AF_UNSPEC, sa_data="\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}, 16) = 0 <0.000019>
28636 10:33:49 connect(6, {sa_family=AF_INET, sin_port=htons(6493), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 <0.000020>
28636 10:33:49 getsockname(6, {sa_family=AF_INET6, sin6_port=htons(37600), inet_pton(AF_INET6, "::ffff:127.0.100.1", &sin6_addr), sin6_flowinfo=0, sin6_scope
_id=0}, [28]) = 0 <0.000015>
28636 10:33:49 close(6)                 = 0 <0.000013>
28636 10:33:49 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 6 <0.000020>
28636 10:33:49 setsockopt(6, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 <0.000015>
28636 10:33:49 bind(6, {sa_family=AF_INET, sin_port=htons(6493), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 <0.000012>
28636 10:33:49 socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP) = 7 <0.000017>
28636 10:33:49 socket(PF_FILE, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 8 <0.000012>
28636 10:33:49 connect(8, {sa_family=AF_FILE, path="/dev/log"}, 110) = -1 EPROTOTYPE (Protocol wrong type for socket) <0.000016>
28636 10:33:49 close(8)                 = 0 <0.000016>
28636 10:33:49 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC, 0) = 8 <0.000012>
28636 10:33:49 connect(8, {sa_family=AF_FILE, path="/dev/log"}, 110) = 0 <0.000033>
28636 10:33:49 sendto(8, "<39>Nov 12 10:33:49 sshd[28636]: debug3: sock_set_v6only: set socket 7 IPV6_V6ONLY\0", 83, MSG_NOSIGNAL, NULL, 0) = 83 <0.000047>
28636 10:33:49 close(8)                 = 0 <0.000024>
28636 10:33:49 setsockopt(7, SOL_IPV6, IPV6_V6ONLY, [1], 4) = 0 <0.000011>
28636 10:33:49 setsockopt(7, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 <0.000021>
28636 10:33:49 bind(7, {sa_family=AF_INET6, sin6_port=htons(6493), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EADDRN
OTAVAIL (Cannot assign requested address) <0.000020>
28636 10:33:49 socket(PF_FILE, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 8 <0.000020>
28636 10:33:49 connect(8, {sa_family=AF_FILE, path="/dev/log"}, 110) = -1 EPROTOTYPE (Protocol wrong type for socket) <0.000016>
28636 10:33:49 close(8)                 = 0 <0.000020>
28636 10:33:49 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC, 0) = 8 <0.000020>
28636 10:33:49 connect(8, {sa_family=AF_FILE, path="/dev/log"}, 110) = 0 <0.000040>
28636 10:33:49 sendto(8, "<39>Nov 12 10:33:49 sshd[28636]: debug2: bind port 6493: Cannot assign requested address\0", 89, MSG_NOSIGNAL, NULL, 0) = 89 <0.000
055>
28636 10:33:49 close(8)                 = 0 <0.000031>
28636 10:33:49 close(7)                 = 0 <0.000021>
28636 10:33:49 close(6)                 = 0 <0.000020>
Comment 1 Arkadiusz Miśkiewicz 2011-11-12 21:49:21 AEDT
Created attachment 2106 [details]
skip family if address is unavailable (EADDRNOTAVAIL)

Patch that makes sshd listen on ipv4 socket in such situation and avoid looping until MAX_DISPLAYS is reached.
Comment 2 Darren Tucker 2011-11-13 13:10:15 AEDT
It tries to bind to IPv6 because getaddrinfo tells it to, even though bind will never work.

Unfortunately, your patch reintroduces the problem described in CVE-2008-1483.  As a workaround you can set AddressFamily inet in sshd_config, or fix getaddrinfo.

See:
http://marc.info/?l=openssh-unix-dev&m=123378783531913&w=2
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1483
Comment 3 Arkadiusz Miśkiewicz 2011-11-13 18:22:49 AEDT
Hm, but EADDRNOTAVAIL means address is not available, so nothing else could be listening (EADDRNOTAVAIL vs EADDRINUSE), right?
Comment 4 Damien Miller 2012-02-24 11:39:37 AEDT
I think using AI_ADDRCONFIG might be a better solution here, but IMO it makes some attacks possible too (e.g. a sshd that accepts an X11 forwarding connection before ipv6 is ready)
Comment 5 Damien Miller 2019-01-23 20:10:33 AEDT
obsolete; closing
Comment 6 Damien Miller 2019-05-03 14:42:37 AEST
Move resolved bugs -> CLOSED after 8.0 release