Subject: bin/11261: ssh does getsockopt() on wrong file descriptor
To: None <gnats-bugs@gnats.netbsd.org>
From: None <eramore@era-t.ericsson.se>
List: netbsd-bugs
Date: 10/19/2000 02:51:21
>Number:         11261
>Category:       bin
>Synopsis:       ssh does getsockopt() on wrong file descriptor
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Oct 19 02:51:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Michael Eriksson
>Release:        1.5_ALPHA2 (the same bug is in -current)
>Organization:
Ericsson Radio Systems AB
>Environment:
System: NetBSD kafka 1.5_ALPHA2 NetBSD 1.5_ALPHA2 (KAFKA) #0: Fri Oct 13 13:43:06 CEST 2000 mer@kafka:/usr/src/sys/arch/i386/compile/KAFKA i386


>Description:

ssh does a getsockopt(IP_OPTIONS) to check that there are no IP
options on incoming forwarded connections. Unfortunately, it does this
on the wrong file descriptor, namely 0 (standard input) instead of the
incoming socket.

This bug is benign when stdin is a tty (getsockopt() returns
ENOTSOCK), but if stdin is a pipe getsockopt() returns four null bytes
as IP options, and ssh complains and exits.

(That getsockopt(IP_PROTO, IP_OPTIONS) on a pipe returns four null
bytes rather than an error is arguably another bug.)

>How-To-Repeat:

bolle>echo foo | ssh -f -L 4711:localhost:25 kafka sleep 60 ; sleep 2 ; telnet localhost 4711
Trying 127.0.0.1...
Connection from 127.0.0.1 with IP options: 00 00 00 00
Connected to localhost.
Disconnecting: Connection from 127.0.0.1 with IP options: 00 00 00 00
Escape character is '^]'.
Connection closed by foreign host.

>Fix:

Index: canohost.c
===================================================================
RCS file: /cvsroot/basesrc/crypto/dist/ssh/canohost.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 canohost.c
--- canohost.c	2000/09/28 22:09:48	1.1.1.1
+++ canohost.c	2000/10/19 09:46:43
@@ -131,7 +131,7 @@
 		else
 			ipproto = IPPROTO_IP;
 		option_size = sizeof(options);
-		if (getsockopt(0, ipproto, IP_OPTIONS, (char *) options,
+		if (getsockopt(socket, ipproto, IP_OPTIONS, (char *) options,
 		    &option_size) >= 0 && option_size != 0) {
 			cp = text;
 			/* Note: "text" buffer must be at least 3x as big as options. */
>Release-Note:
>Audit-Trail:
>Unformatted: