5.2: Solaris 10 x86 x-11 forwarding fails, assign requested address

Seth Ellsworth Seth.Ellsworth at quest.com
Tue May 25 06:46:12 EST 2010


This is on Solaris 10 x86, do not see this behavior on Solaris 10 sparc. Seen on multiple machines.

Sshd debug:
debug1: server_input_channel_open: ctype session rchan 256 win 16384 max 16384
debug1: input_session_request
debug1: channel 0: new [server-session]
debug2: session_new: allocate (allocated 0 max 10)
debug3: session_unused: session id 0 unused
debug1: session_new: session 0
debug1: session_open: channel 0
debug1: session_open: session 0: link with channel 0
debug1: server_input_channel_open: confirm session
debug1: server_input_channel_req: channel 0 request x11-req reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req x11-req
debug2: bind port 6010: Cannot assign requested address
debug2: bind port 6011: Cannot assign requested address
debug2: bind port 6012: Cannot assign requested address
...
debug2: bind port 6997: Cannot assign requested address
debug2: bind port 6998: Cannot assign requested address
debug2: bind port 6999: Cannot assign requested address
Failed to allocate internet-domain X11 display socket.
debug1: x11_create_display_inet failed.


In a previous version, 4.7, this worked, and looked like:
debug1: server_input_channel_req: channel 0 request x11-req reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req x11-req
debug2: bind port 6010: Cannot assign requested address
debug2: fd 7 setting O_NONBLOCK
debug3: fd 7 is O_NONBLOCK
debug1: channel 1: new [X11 inet listener]
debug1: server_input_channel_req: channel 0 request exec reply 1


Looking at differences between the 4.7 and 5.2 ( 5.5 is the same in this regards ), the difference seems to be in:
channels.c
Function: x11_create_display_inet
Line:2908: ( 4.7p1 code )
                if (ai->ai_next)
                    continue;
That's right after the bind fails.

If I follow the behavior, the first ai from getaddrinfo is an IPV6 address that's not valid. Errno is EADDRNOTAVAIL.

Now in 4.7 the continue would make it just try the next ai.
In 5.2 that continue isn't there, so instead it breaks and tries the next port number, on the same ai, which fails all the way until MAX_DISPLAYS is reached.

For this situation I want to put back the if/continue, but I assume it was removed for a reason, and wanted to find out if anyone here knew.



Ok, found the cvsweb, and located this:
Revision 1.272.2.1: download<http://www.openbsd.org/cgi-bin/cvsweb/%7Echeckout%7E/src/usr.bin/ssh/channels.c?rev=1.272.2.1;content-type=text%2Fplain> - view: text<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/channels.c?rev=1.272.2.1;content-type=text%2Fplain>, markup<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/channels.c?rev=1.272.2.1;content-type=text%2Fx-cvsweb-markup>, annotated<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/channels.c?annotate=1.272.2.1> - select for diffs<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/channels.c?r1=1.272.2.1#rev1.272.2.1>
Thu Apr 3 03:42:02 2008 UTC (2 years, 1 month ago) by brad
Branches: OPENBSD_4_3<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/channels.c?only_with_tag=OPENBSD_4_3>
Diff to: previous 1.272: preferred<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/channels.c.diff?r1=1.272;r2=1.272.2.1>, coloured<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/channels.c.diff?r1=1.272;r2=1.272.2.1;f=h>; next MAIN 1.273: preferred<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/channels.c.diff?r1=1.273;r2=1.272.2.1>, coloured<http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/channels.c.diff?r1=1.273;r2=1.272.2.1;f=h>
Changes since revision 1.272: +1 -4 lines

avoid possible hijacking of x11-forwarded connections (back out 1.183)

CVE-2008-1483; ok djm@


Ok, this was removed to address an attack type. So, how do I fix this so I keep the needed behavior but don't introduce the vulnerability?

The root of the problem seems to be getting an invalid IPV6 addrinfo, and that failure means it doesn't try any other addrofinfo's, instead looping on port's, which all fail, because the addrinfo always fails.

How about adding it back under certain circumstances:
sellswor at sethe:~/tmp/2/openssh-5.5p1> diff -u channels.c channels.c.orig
--- channels.c  2010-05-24 14:44:15.000000000 -0600
+++ channels.c.orig     2010-05-24 14:43:32.000000000 -0600
@@ -3271,13 +3271,9 @@
                        if (x11_use_localhost)
                                channel_set_reuseaddr(sock);
                        if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
-                int loc_errno = errno;
                                debug2("bind port %d: %.100s", port, strerror(errno));
                                close(sock);

-                if( loc_errno == EADDRNOTAVAIL && ai->ai_next )
-                    continue;
-
                                for (n = 0; n < num_socks; n++) {
                                        close(socks[n]);
                                }
You have new mail in /var/spool/mail/sellswor
sellswor at sethe:~/tmp/2/openssh-5.5p1>

Thoughts?

Am I approaching this wrong, and this shows a mis-configured machine? ( happens on multiple machines, all default setups connected to IPV4 networks ).
---
Seth Ellsworth
Vintela Development
The people and products of Vintela are now a part of Quest Software.
Read the press release<dhtmled5://exchweb/bin/redir.asp?URL=http://www.quest.com/news/show.asp?ContentId=1826%26ContentTypeId=2%26site=> to learn more.


More information about the openssh-unix-dev mailing list