From: <ha...@no...> - 2002-05-17 14:43:55
|
It seemes that setsid() does not set 'leader' flag for masq-ed processes. This probably may be fixed in bproc-3.1.10/kernel/masq.c: int masq_setsid(void) { ... current->bproc.masq->session = current->bproc.masq->pgrp = current->bproc.masq->pid; current->leader = 1; /* this line added by Vaclav Hanzl */ return current->bproc.masq->pgrp; ... and following ioctl(TIOCSCTTY) then may succeed. However this change would probably also trigger some now dormant parts of kernel code (e.g. SIGHUP related things) which have never run for masq-ed process so far and may either work or fail terribly. Fortunately in kernel there are just few places where the 'leader' flag is used: include/linux/sched.h: defined here kernel/fork.c: child gets 0 kernel/sys.c: (should be) set in sys_setsid() kernel/exit.c: if set, call disassociate_ctty(1) in tty_io.c kernel/signal.c: kill_sl_info() sends a signal to the session leader: this is used to send SIGHUP to the controlling process of a terminal when the connection is lost. /* XXX bproc: Need ways to deal with session leaders...*/ drivers/char/tty_io.c: do_tty_hangup() sends SIGHUP&SIGCONT to leader disassociate_ctty() defined here (called for leader) tty_open() associates tty and leader tiocsctty() works for leader only (our problem) tty_ioctl(TIOCNOTTY) calls disassociate_ctty(0) for leader I am not sure what happens when sending SIGHUP and SIGCONT, there might even be some potential deadlock (??) but these things are beyond my imagination - any opinions welcome. The above "XXX bproc..." comment suggests we might step out to empty spaces... Here is my reconstruction of things that happen before sshd fails on ioctl(TIOCSCTTY): 1. in openssh-3.1p1/sshpty.c, pty_allocate(): all goes well, new pty allocated for incoming ssh login 2. in openssh-3.1p1/sshpty.c, pty_make_controlling_tty(): would like to create new session, calls setsid() 3. in linux-2.4.18-lanl.16/kernel/sys.c: sys_setsid(){ ... bproc_hook_imr(sys_setsid,()); process is masq-ed, so it goes to hook and will return what hook returns 4. in bproc-3.1.10/kernel/hooks.c: int bproc_hook_sys_setsid(void) { return masq_setsid(); } 5. in bproc-3.1.10/kernel/masq.c: int masq_setsid(void) { ... current->bproc.masq->session = current->bproc.masq->pgrp = current->bproc.masq->pid; return current->bproc.masq->pgrp; returns WITHOUT setting current->leader = 1 6. back in openssh-3.1p1/sshpty.c, pty_make_controlling_tty(): Wants to set controlling tty using TIOCSCTTY: ioctl(*ttyfd, TIOCSCTTY, NULL) 7. in linux-2.4.18-lanl.16/drivers/char/tty_io.c: tty_ioctl(){ ... case TIOCSCTTY: return tiocsctty(tty, arg); tiocsctty(){ ... if (!current->leader || current->tty) return -EPERM; ... current->leader should be 1 but is 0 8. in openssh-3.1p1/sshpty.c, pty_make_controlling_tty(): sshd logs message "error: ioctl(TIOCSCTTY): Operation not permitted" later on in #ifdef hell it verifies once again and also logs: error: open /dev/tty failed - could not set controlling tty: No such file or directory Thanks to Wilton Wong who suggested to me: > Try putting the setgpid callbefore the setsid call.. that I think will at > least fix the bash error, but won't do anything about controlling tty.. > setsid() and stuff is mostly voodoo magic as fas as I am concernerd.. I tested this. When setpgid(0, getpid()) is before setsid() in sshd, bash starts without complaints (and without Ctrl-C functionality), sshd is happy with setpgid(0, getpid()) and setsid() now failes: n1 sshd[21367]: error: setsid: Operation not permitted n1 sshd[21367]: error: ioctl(TIOCSCTTY): Operation not permitted n1 sshd[21367]: error: open /dev/tty failed - could not set controlling tty: No such file or directory This drew my attention to strange fact that setsid() should set leader flag and ioctl(TIOCSCTTY) does not see it. Thanks also to Erik Arjan Hendriks for his comments. DISCLAIMER: I did NOT try to run kernel with the proposed fix in bproc. There may be more strange things to come. Best Regards Vaclav Hanzl |