Bug 2143 - X11 forwarding for ipv4 is broken when ipv6 is disabled on the loopback interface
Summary: X11 forwarding for ipv4 is broken when ipv6 is disabled on the loopback inter...
Status: NEW
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sshd (show other bugs)
Version: 5.3p1
Hardware: All Linux
: P5 minor
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-08-25 05:10 AEST by Grier Ellis
Modified: 2020-03-31 23:04 AEDT (History)
9 users (show)

See Also:


Attachments
Suggested patch to fix X11 forwarding with IPv6 disabled (593 bytes, patch)
2013-09-16 03:45 AEST, Andrey Borzenkov
no flags Details | Diff
generally skip throwing away opened sockets on EADDRNOTAVAIL (1.04 KB, patch)
2017-08-30 06:27 AEST, Petr Cerny [:hrosik]
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Grier Ellis 2013-08-25 05:10:55 AEST
I haven't seen this exact bug reported, even on the current version.

If the ipv6 kernel module is loaded, and ipv6 is disabled on the loopback interface, X forwarding (for ipv4, at least) is broken, unless AddressFamily is set to "inet".

It seems that sshd will refuse to listen for X connections on ipv4 if it can't open an ipv6 socket.  It listens for ssh connections on ipv4 either way, so this appears to be a bug.

Test by toggling /proc/sys/net/ipv6/conf/lo/disable_ipv6.

I could probably find the problem in the code, as I used to be a fairly competent c programmer, but I just don't have the time.
Comment 1 Loganaden Velvindron 2013-08-26 01:45:13 AEST
(In reply to Grier Ellis from comment #0)
> I haven't seen this exact bug reported, even on the current version.
> 
> If the ipv6 kernel module is loaded, and ipv6 is disabled on the
> loopback interface, X forwarding (for ipv4, at least) is broken,
> unless AddressFamily is set to "inet".
> 
> It seems that sshd will refuse to listen for X connections on ipv4
> if it can't open an ipv6 socket.  It listens for ssh connections on
> ipv4 either way, so this appears to be a bug.
> 
> Test by toggling /proc/sys/net/ipv6/conf/lo/disable_ipv6.

I can confirm that the bug exists with -current as well.

I was able to reproduce it in our dual-stack environment.
> 
> I could probably find the problem in the code, as I used to be a
> fairly competent c programmer, but I just don't have the time.

I'm looking at the code right now. This looks very interesting :-)
Comment 2 Andrey Borzenkov 2013-09-16 03:45:52 AEST
Created attachment 2335 [details]
Suggested patch to fix X11 forwarding with IPv6 disabled

The problem is that getaddrinfo() without hints flags returns both IPv4 and IPv6 localhost addresses. There are two possible fixes:

1. add AI_ADDRCONFIG. This will work around this bug if IPv6 is globally disabled, because no interface will have IPv6 address, but still fails in corner case when some interface does have IPv6 but localhost not.

2. Simply ignore this error. That is what generic forwarding does anyway.

Attached patch implements #2. It tries to limit cases when we ignore error to exactly IPv6 and address not available, but may be we can simplify it and simply follow generic forwarding example.
Comment 3 Darren Tucker 2014-11-06 04:49:16 AEDT
Note that just ignoring the error will re-introduce http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1483
Comment 4 Andrey Borzenkov 2014-12-12 05:33:32 AEDT
(In reply to Darren Tucker from comment #3)
> Note that just ignoring the error will re-introduce
> http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-1483

Patch ignores one specific error only - EADDRNOTAVAIL. bind returns it when requested address is not present on host. If listening address is present, bind fails with EADDRINUSE and current behavior is not changed.
Comment 5 Petr Cerny [:hrosik] 2017-08-30 06:27:17 AEST
Created attachment 3044 [details]
generally skip throwing away opened sockets on EADDRNOTAVAIL

I'm suppose the same could (in the future) happen for IPv4 (or other protocols), it might be better not to limit it to IPv6.

Darren, do you have any concerns about this sort of limiting? AFAIU, the only way CVE-2008-1483 could creep back in is that someone enables disabled protocol and starts listening on the same port that is already used (with the address family that was available at the moment the connection was established).
Comment 6 Jakub Jelen 2017-11-09 00:52:53 AEDT
ping. Is there any update on this?

To my understanding and testing, the patch provided by Petr does NOT expose the linked CVE, because the attack really depends on the ignoring EADDRINUSE errno, which was the problem of implementation before OpenSSH 5.0 but not of this patch.

I believe that it is not a priority for you, but on some systems with disabled IPv6 this issue is pretty annoying. I can see in this bug that there are at least three people who believe it is a bug and that this patch is solving the problem without introducing any regression in security.

So is there any chance to have this patch reviewed/accepted?
Comment 7 Andrey 2018-11-11 16:35:34 AEDT
Still broken in 7.8p1 on Linux with IPv6 enabled in the kernel (CONFIG_IPV6=y), but disabled (/proc/sys/net/ipv6/conf/lo/disable_ipv6) at runtime.

Specifying "AddressFamily inet" fixes the problem.
Toggling "disable_ipv6" back also "fixes" the problem.

Setting "X11UseLocalhost no" also workarounds the problem in a more dangerous way.
Comment 8 Bill McGonigle 2020-02-13 10:17:12 AEDT
I ran into this on a current Debian machine with ipv6.disable=1 on the kernel command line (completely disables IPv6 at boot time).

When searching for:

  X11 forwarding request failed on channel 0

I came across many articles/stackexchanges offering advice for fixing this, basically all saying to set:

  X11UseLocalhost no

Since everything works after setting it, it seems like "the fix" to people who implement it.  Being naturally paranoid, I read the man page, and, horrified, I went looking further.  I found:

  AddressFamily inet

which works properly for this machine, though it should be noted that none of the other daemons running on it fail functionality with IPv6 disabled.

My concern is that by not addressing this problem, many users are configuring their machines insecurely.  I see there are some security concerns noted above if this isn't fixed correctly, but it needs to be pointed out that not fixing it also has security concerns on an ecosystem level.

Are there any concrete security objections to either of the proposed patches?

SuSE appears to be carrying Andrev's patch.
Comment 9 Alan D. Salewski 2020-03-31 23:04:21 AEDT
[Just want to note this experience and workaround for other Debian users who
 might wander through here...]

I ran into this on a current Debian machine with the 'openssh-server' package
version 1:8.2p1-4.

IPv6 is disabled on the host, but via a runtime sysctl.d/ file rather than the
kernel command line option. The sysctl config file contains the settings:

    net.ipv6.conf.all.disable_ipv6 = 1
    net.ipv6.conf.default.disable_ipv6 = 1

After cranking-up the sshd debug logging, I would see a ton of messages like
the following in /var/log/auth.log when a client would connect with X11
forwarding requested ('-X'):

    Mar 31 06:22:42 myhostname sshd[3187]: debug2: x11_create_display_inet: bind port 6011: Cannot assign requested address
    Mar 31 06:22:42 myhostname sshd[3187]: debug3: sock_set_v6only: set socket 9 IPV6_V6ONLY

Unlike the documented experience of others (above, and elsewhere on the Net),
setting[0] 'AddressFamily inet' *did not* correct the problem for me. However,
adding '-4' to the (otherwise empty) sshd startup options via the
'/etc/default/ssh' file did work.


[0] Actually, it was already set explicitly.