| Summary: | SSH can not log out under Solaris 2.6 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | Portable OpenSSH | Reporter: | Bob Friesenhahn <bfriesen> | ||||||
| Component: | sshd | Assignee: | OpenSSH Bugzilla mailing list <openssh-bugs> | ||||||
| Status: | CLOSED FIXED | ||||||||
| Severity: | critical | CC: | AVShutko, dawagner, john.carroll, js, sam | ||||||
| Priority: | P2 | ||||||||
| Version: | -current | ||||||||
| Hardware: | UltraSPARC | ||||||||
| OS: | Solaris | ||||||||
| Attachments: |
|
||||||||
|
Description
Bob Friesenhahn
2002-05-17 14:03:09 AEST
Same issue with Solaris 8 built with gcc 2.95.2 with the following configure options: --without-rsh --with-tcp-wrappers --with-pam --disable-suid-ssh --with-prngd-socket --with-default-path=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin Running a ssh -v -v -v hangs up at the following point (I will happily attach the entire output of this if anyone wants) $ exit logout debug1: client_input_channel_req: channel 0 rtype exit-status reply 0 Hung here until sshd killed debug1: channel_free: channel 0: client-session, nchannels 1 debug3: channel_free: status: The following connections are open: #0 client-session (t4 r0 i0/0 o0/0 fd 5/6) debug3: channel_close_fds: channel 0: r 5 w 6 e 7 Connection to oraadm closed by remote host. Connection to oraadm closed. debug1: Transferred: stdin 0, stdout 0, stderr 75 bytes in 55.7 seconds debug1: Bytes per second: stdin 0.0, stdout 0.0, stderr 1.3 debug1: Exit status 0 Unfortunately, running sshd with -d -d -d doesn't completely capture the problem, as the sshd promptly exits after the first connection closes down (though this does point to the fact that sshd is able to close). The only oddity in the sshd -d -d -d is the following message (last message issued before finishing): debug1: Cannot delete credentials[7]: Permission denied *** Bug 247 has been marked as a duplicate of this bug. *** i don't know why yet, but the setsid() added to sshd.c seems to break pty_make_controlling_tty(). will add a patch to try. Created attachment 96 [details]
remove call to setsid()
The patch allows logout to occur, and I note that version 3.1p1 run with -d -d -d also ends with "debug1: Cannot delete credentials[7]: Permission denied", so this is not related. I also note that this patch solves the problem reported on openssh-unix-dev@mindrot.org in an e-mail by Greg Jewell <gjewell@cnnxn.com>, wherein hitting Ctrl-C will break a connection (I both confirmed the problem without the patch and the lack of the problem with the patch). The suggested patch resolves the logout problem on my system. Is it the right fix? *** Bug 249 has been marked as a duplicate of this bug. *** *** Bug 250 has been marked as a duplicate of this bug. *** Another manifestation of the bug, on solaris 8, was that the ps command broke, with the message "no controlling terminal". Using the proposed patch solved the problem completely. i think this is related to this bug, compiling 3.2.2p1 for solaris 8, using gcc 3.2 or 2.95.3 will give the following error when logging into tcsh "Warning: no access to tty (Inappropriate ioctl for device). Thus no job control in this shell." in addition to hang on logout. this error does not occur in openssh 3.1p1 on the same machine. right forgot to mention in my earlier comment regarding this bug -- login into sh seems to work just fine. not tcsh though, have not tried other shells An explanation of the problem is provided by the man page for setsid() on
Solaris. I'm fairly sure that the behaviour specified is per POSIX.
DESCRIPTION
The setsid() function creates a new session, if the calling
process is not a process group leader. Upon return the cal-
ling process will be the session leader of this new session,
will be the process group leader of a new process group, and
will have no controlling terminal.
The lack of controlling terminal appears to be the key issue.
hey the patch, id=96, seemed to fix these problems altogether... :) thanks - (stevesk) [sshd.c] bug 245; disable setsid() for now Hi there, additional informations: I installed openssh3.2.2p1 under Solaris 2.6 with the following solution I found in the mailinglist (I wonder that the same error is still in it ...) #define _FILE_OFFSET_BITS 64 (This is already in) #define _LARGEFILE64_SOURCE (This I added) into config.h. So I got also the message that is meantioned from tcsh, it apears when starting a new shell. "Warning: no access to tty (Inappropriate ioctl for device). Thus no job control in this shell." But also I got a similar message when starting bash instead: "bash: no job control in this shell" So if one already applied the patch please check this behavior? greetings, pitu *** Bug 272 has been marked as a duplicate of this bug. *** asked millert@openbsd.org. we still don't know why setsid() breaks solaris. Did some digging on this. Carson seems to be correct in that the problem is due
to missing controlling terminal.
I uncommented the setsid() in sshd.c and added some debugging log() calls to
sshd, which generated the following:
sshd[21690]: main: before setsid sid=21460
sshd[21690]: main: after setsid sid=21690
sshd[21690]: Accepted publickey for dtucker from 192.168.1.1 port 1665 ssh2
sshd[21694]: pty_make_controlling_tty called, ttyfd=7, cttyname=/dev/pts/2
sshd[21694]: pty_make_controlling_tty: file descriptor 7 is tty /dev/pts/2
sshd[21694]: pty_make_controlling_tty: before setsid, ppid=21690, sid=21690
sshd[21694]: pty_make_controlling_tty: after setsid, ppid=21690, sid=21694
sshd[21694]: error: open /dev/tty failed - could not set controlling tty: No
such device or address
# ps -l -p 21690,21694
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
c8 S 500 21694 21690 1 44 20 f62bd7a0 618 f66d18fe ? 0:00 bash
c8 S 0 21690 21460 1 46 20 f65c17c0 650 f66a6d92 pts/2 0:01 sshd
Note that sshd has picked up a controlling terminal.
# ps -j -p 21690,21694
PID PGID SID TTY TIME CMD
21694 21694 21694 ? 0:00 bash
21690 21690 21690 pts/2 0:01 sshd
So what seems to be happening is:
1) sshd daemon forks process to handle connection
2) sshd child calls setsid and becomes session leader
3) child allocates pty, and aquires new pty as controlling terminal
4) child forks again, calls setsid and attempts to make pty controlling
terminal. This fails because the pty is already controlling terminal for another
session.
Looking at a truss -f of sshd for access to that pty shows:
# grep /dev/pt /tmp/sshd.trace |grep 21690
21690: open64("/dev/ptmx", O_RDWR|O_NOCTTY) = 6
21690: access("/dev/pts/2", 0) = 0
21690: open64("/dev/pts/2", O_RDWR|O_NOCTTY) = 7
21690: stat64("/dev/pts/2", 0xEFFFF020) = 0
21690: chown("/dev/pts/2", 500, 7) = 0
My guess is that one of the accesses without the O_NOCTTY flag accidently picks
up the newly allocated pty as the controlling terminal.
Update: splitting out the pty ops into a test program shows that pushing the
STREAMS modules is what causes the controlling terminal to be acquired, ie
sshpty.c:132
if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
error("ioctl I_PUSH ptem: %.100s", strerror(errno));
From the man page of streamio:
I_PUSH
Pushes the module whose name is pointed to by arg onto
the top of the current stream, just below the STREAM
head. If the STREAM is a pipe, the module will be
inserted between the stream heads of both ends of the
pipe. It then calls the open routine of the newly-
pushed module. On failure, errno is set to one of the
following values:
Want to bet it's the "open routine" that acquires the controlling tty? If that's
so the the only way I can see to fix it is push the STREAMS modules *after*
forking to run the shell.
That cure might be worse than the disease.
The root cause appears to be an 8-year-old bug in Solaris (Sun bugid 1156877).
The bug is marked "fixed" but the testcase fails on my Solaris 8 box (with
recommended patches from a few weeks ago).
[quote]
The open routine of the master-side pty driver (ptm) sends an
M_SETOPTS message to the stream head that, among other things,
has the SO_ISTTY bit set. This action has the effect of expressing
willingness to act as a controlling tty. However, it is nonsensical
for the driver to do so, since it supports none of the other tty
semantics.
[snip]
However, opening /dev/ptmx with O_NOCTTY
only prevents the problem until the user pushes another module on the
stream head. Note that this only happens if the process has no controlling
terminal already.
[snip]
Work Around
Open the master-side pty with the O_NOCTTY open flag.
This works only if you don't push any streams modules - a
rather special case.
[/quote]
A rather obnoxious work-around would be to close the tty in the parent (thus removing it as the controlling terminal for that process). Unfortunately, the child would have to be told somehow that the parent is done closing the tty, and that is annoying to do well. Created attachment 187 [details]
Don't call setsid() on Solaris only
Applied - thanks. In case anyone finds this again, I had a similar problem, reporting: Sep 19 16:51:06 wallace sshd[13159]: [ID 800047 local0.error] error: open /dev/tty failed - could not set controlling tty: Permission denied It turned out to be insufficient permissions on /dev/tty. Should be crw-rw-rw- Mass change of RESOLVED bugs to CLOSED |