Bugzilla – Attachment 34570 Details for
Bug 65372
VUL-0: CVE-2005-0178: kernel: tty/setsid race
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
IDP Log In
|
Forgot Password
[patch]
patch for SLES9 SP1
setsid-tty-locking.SP1 (text/plain), 7.54 KB, created by
Karsten Keil
on 2005-04-15 12:45:18 UTC
(
hide
)
Description:
patch for SLES9 SP1
Filename:
MIME Type:
Creator:
Karsten Keil
Created:
2005-04-15 12:45:18 UTC
Size:
7.54 KB
patch
obsolete
>From: Alan Cox <alan@lxorguk.ukuu.org.uk> >Subject: Fix tty setsid race backport >Reference: 65372 >Acked-by: kkeil@suse.de > ># This is a BitKeeper generated diff -Nru style patch. ># ># ChangeSet ># 2005/01/06 16:40:16-08:00 alan@lxorguk.ukuu.org.uk ># [PATCH] First cut at setsid/tty locking ># ># Use the existing "tty_sem" to protect against the process tty changes ># too. ># ># drivers/char/tty_io.c ># 2005/01/04 11:42:29-08:00 alan@lxorguk.ukuu.org.uk +29 -10 ># First cut at setsid/tty locking ># ># kernel/exit.c ># 2005/01/04 10:45:27-08:00 alan@lxorguk.ukuu.org.uk +2 -0 ># First cut at setsid/tty locking ># ># kernel/sys.c ># 2005/01/04 10:47:32-08:00 alan@lxorguk.ukuu.org.uk +2 -0 ># First cut at setsid/tty locking ># >diff -urN linux-2.6.5.old/drivers/char/tty_io.c linux-2.6.5/drivers/char/tty_io.c >--- linux-2.6.5.old/drivers/char/tty_io.c 2005-04-15 11:06:34.014424240 +0200 >+++ linux-2.6.5/drivers/char/tty_io.c 2005-04-15 12:45:17.350423773 +0200 >@@ -122,6 +122,9 @@ > LIST_HEAD(tty_drivers); /* linked list of tty drivers */ > struct tty_ldisc ldiscs[NR_LDISCS]; /* line disc dispatch table */ > >+/* Semaphore to protect creating and releasing a tty */ >+DECLARE_MUTEX(tty_sem); >+ > #ifdef CONFIG_UNIX98_PTYS > extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ > extern int pty_limit; /* Config limit on Unix98 ptys */ >@@ -567,9 +570,11 @@ > > lock_kernel(); > >+ down(&tty_sem); > tty = current->signal->tty; > if (tty) { > tty_pgrp = tty->pgrp; >+ up(&tty_sem); > if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) > tty_vhangup(tty); > } else { >@@ -577,6 +582,7 @@ > kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit); > kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit); > } >+ up(&tty_sem); > unlock_kernel(); > return; > } >@@ -586,14 +592,18 @@ > kill_pg(tty_pgrp, SIGCONT, on_exit); > } > >+ /* Must lock changes to tty_old_pgrp */ >+ down(&tty_sem); > current->signal->tty_old_pgrp = 0; > tty->session = 0; > tty->pgrp = -1; > >+ /* Now clear signal->tty under the lock */ > read_lock(&tasklist_lock); > for_each_task_pid(current->signal->session, PIDTYPE_SID, p, l, pid) > p->signal->tty = NULL; > read_unlock(&tasklist_lock); >+ up(&tty_sem); > unlock_kernel(); > } > >@@ -758,19 +768,6 @@ > return tty_write(file, buf, count, ppos); > } > >-/* Semaphore to protect creating and releasing a tty */ >-static DECLARE_MUTEX(tty_sem); >- >-static void down_tty_sem(int index) >-{ >- down(&tty_sem); >-} >- >-static void up_tty_sem(int index) >-{ >- up(&tty_sem); >-} >- > static void release_mem(struct tty_struct *tty, int idx); > > static char ptychar[] = "pqrstuvwxyzabcde"; >@@ -803,12 +800,6 @@ > struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; > int retval=0; > >- /* >- * Check whether we need to acquire the tty semaphore to avoid >- * race conditions. For now, play it safe. >- */ >- down_tty_sem(idx); >- > /* check whether we're reopening an existing tty */ > if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { > tty = devpts_get_tty(idx); >@@ -989,9 +980,7 @@ > success: > *ret_tty = tty; > >- /* All paths come through here to release the semaphore */ > end_init: >- up_tty_sem(idx); > return retval; > > /* Release locally allocated memory ... nothing placed in slots */ >@@ -1184,9 +1173,14 @@ > * each iteration we avoid any problems. > */ > while (1) { >+ /* Guard against races with tty->count changes elsewhere and >+ opens on /dev/tty */ >+ >+ down(&tty_sem); > tty_closing = tty->count <= 1; > o_tty_closing = o_tty && > (o_tty->count <= (pty_master ? 1 : 0)); >+ up(&tty_sem); > do_sleep = 0; > > if (tty_closing) { >@@ -1222,6 +1216,8 @@ > * both sides, and we've completed the last operation that could > * block, so it's safe to proceed with closing. > */ >+ >+ down(&tty_sem); > if (pty_master) { > if (--o_tty->count < 0) { > printk(KERN_WARNING "release_dev: bad pty slave count " >@@ -1235,7 +1231,8 @@ > tty->count, tty_name(tty, buf)); > tty->count = 0; > } >- >+ up(&tty_sem); >+ > /* > * We've decremented tty->count, so we need to remove this file > * descriptor off the tty->tty_files list; this serves two >@@ -1343,11 +1340,17 @@ > int index; > dev_t device = inode->i_rdev; > unsigned short saved_flags = filp->f_flags; >+ > retry_open: > noctty = filp->f_flags & O_NOCTTY; >+ >+ down(&tty_sem); >+ > if (device == MKDEV(TTYAUX_MAJOR,0)) { >- if (!current->signal->tty) >+ if (!current->signal->tty) { >+ up(&tty_sem); > return -ENXIO; >+ } > driver = current->signal->tty->driver; > index = current->signal->tty->index; > filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ >@@ -1377,6 +1380,7 @@ > noctty = 1; > goto got_driver; > } >+ up(&tty_sem); > return -ENODEV; > } > >@@ -1402,22 +1406,28 @@ > goto ptmx_found; /* ok! */ > } > } >+ up(&tty_sem); > return -EIO; /* no free ptys */ > ptmx_found: > set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ > if (devpts_pty_new(tty->link)) { > /* BADNESS - need to destroy both ptm and pts! */ >+ up(&tty_sem); > return -ENOMEM; > } > noctty = 1; >+ up(&tty_sem); > } else > #endif > { > driver = get_tty_driver(device, &index); >- if (!driver) >+ if (!driver) { >+ up(&tty_sem); > return -ENODEV; >+ } > got_driver: > retval = init_dev(driver, index, &tty); >+ up(&tty_sem); > if (retval) > return retval; > } >diff -urN linux-2.6.5.old/drivers/char/vt.c linux-2.6.5/drivers/char/vt.c >--- linux-2.6.5.old/drivers/char/vt.c 2005-04-15 11:06:41.918769701 +0200 >+++ linux-2.6.5/drivers/char/vt.c 2005-04-15 12:33:38.884088694 +0200 >@@ -2489,6 +2489,7 @@ > > static void con_close(struct tty_struct *tty, struct file *filp) > { >+ down(&tty_sem); > acquire_console_sem(); > if (tty && tty->count == 1) { > struct vt_struct *vt; >@@ -2499,9 +2500,15 @@ > tty->driver_data = 0; > release_console_sem(); > vcs_remove_devfs(tty); >+ up(&tty_sem); >+ /* >+ * tty_sem is released, but we still hold BKL, so there is >+ * still exclusion against init_dev() >+ */ > return; > } > release_console_sem(); >+ up(&tty_sem); > } > > static void vc_init(unsigned int currcons, unsigned int rows, unsigned int cols, int do_clear) >diff -urN linux-2.6.5.old/include/linux/tty.h linux-2.6.5/include/linux/tty.h >--- linux-2.6.5.old/include/linux/tty.h 2005-04-15 11:06:30.479611345 +0200 >+++ linux-2.6.5/include/linux/tty.h 2005-04-15 12:37:21.897163779 +0200 >@@ -364,6 +364,9 @@ > extern int tty_get_baud_rate(struct tty_struct *tty); > extern int tty_termios_baud_rate(struct termios *termios); > >+struct semaphore; >+extern struct semaphore tty_sem; >+ > /* n_tty.c */ > extern struct tty_ldisc tty_ldisc_N_TTY; > >diff -urN linux-2.6.5.old/kernel/exit.c linux-2.6.5/kernel/exit.c >--- linux-2.6.5.old/kernel/exit.c 2005-04-15 11:06:41.945760637 +0200 >+++ linux-2.6.5/kernel/exit.c 2005-04-15 11:07:59.733636725 +0200 >@@ -359,7 +359,9 @@ > exit_mm(current); > > set_special_pids(1, 1); >+ down(&tty_sem); > current->signal->tty = NULL; >+ up(&tty_sem); > > /* Block and flush all signals */ > sigfillset(&blocked); >diff -urN linux-2.6.5.old/kernel/sys.c linux-2.6.5/kernel/sys.c >--- linux-2.6.5.old/kernel/sys.c 2005-04-15 11:06:40.103379369 +0200 >+++ linux-2.6.5/kernel/sys.c 2005-04-15 11:07:59.734636389 +0200 >@@ -23,6 +23,7 @@ > #include <linux/security.h> > #include <linux/dcookies.h> > #include <linux/suspend.h> >+#include <linux/tty.h> > #include <linux/ckrm.h> > #include <linux/audit.h> > >@@ -1142,6 +1143,7 @@ > if (!thread_group_leader(current)) > return audit_result(-EINVAL); > >+ down(&tty_sem); > write_lock_irq(&tasklist_lock); > > pid = find_pid(PIDTYPE_PGID, current->pid); >@@ -1155,6 +1157,7 @@ > err = process_group(current); > out: > write_unlock_irq(&tasklist_lock); >+ up(&tty_sem); > return audit_result(err); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 65372
:
28091
|
34500
| 34570