Messages in this thread | | | Date | Sat, 27 Nov 2010 10:43:54 +0100 | From | Jiri Slaby <> | Subject | Re: [PATCH 1/1] TTY: don't allow reopen when ldisc is changing |
| |
On 11/27/2010 09:50 AM, Jiri Slaby wrote: > On 11/27/2010 03:59 AM, Kyle McMartin wrote: >> I'm poking around to see, I think maybe something might be dropping >> locks in the callchain that gives us a window where this might be >> possible... > > Of course, that's the case: > clear_bit(TTY_LDISC, &tty->flags); > tty_unlock(); > cancel_delayed_work_sync(&tty->buf.work); > mutex_unlock(&tty->ldisc_mutex); > > tty_lock(); > mutex_lock(&tty->ldisc_mutex); > > in tty_ldisc_hangup. Hence my point 1) from previous posts doesn't hold too: > 1) __tty_hangup from tty_ldisc_hangup to tty_ldisc_enable. During this > section tty_lock is held. > > I will check, how to fix this.
Reproducible with 2 running processes from the attachment.
regards, -- js suse labs #include <err.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>
#include <sys/ioctl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h>
static void do_work(const char *tty) { char buf[256]; unsigned int cnt = 0; unsigned int errc = 0; int fd, con;
if (signal(SIGHUP, SIG_IGN) == SIG_ERR) err(1, "signal(SIGHUP)");
setsid();
con = open("/tmp/aaa", O_WRONLY|O_NOCTTY|O_CREAT); if (con < 0) err(2, "open cons");
while (1) { if (!(cnt++ % 10000)) { int len = sprintf(buf, "err=%x\n", errc); write(con, buf, len); errc = 0; } fd = open(tty, O_RDWR|O_NOCTTY); if (fd < 0) { errc |= 1; continue; } if (ioctl(fd, TIOCSCTTY)) { errc |= 2; continue; }
if (vhangup()) { errc |= 4; continue; } close(fd); } close(con); exit(errc); }
int main(int argc, char **argv) { pid_t pid;
switch (pid = fork()) { case 0: do_work(argv[1]); break; case -1: err(1, "fork"); break; default: { int stat; waitpid(pid, &stat, 0); if (stat) { fprintf(stderr, "exited with: %d sig=%d signr=%u\n", WEXITSTATUS(stat), WIFSIGNALED(stat), WTERMSIG(stat)); } break; } }
return 0; }
| |