summaryrefslogtreecommitdiffstats
path: root/sys/kern/tty_pts.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-08-04 19:49:05 +0000
committerjhb <jhb@FreeBSD.org>2008-08-04 19:49:05 +0000
commite6ae2f5414dbb59a0d5f60290194dfa8ab1472e5 (patch)
tree2e6b1d6ae2b0c257eef4f5c5132e60496c32604b /sys/kern/tty_pts.c
parent23d4d77b06dff468253bc52d1a1d9a6447bd1e68 (diff)
downloadFreeBSD-src-e6ae2f5414dbb59a0d5f60290194dfa8ab1472e5.zip
FreeBSD-src-e6ae2f5414dbb59a0d5f60290194dfa8ab1472e5.tar.gz
- Close a race with concurrent open's of a pts master device which could
result in leaked tty structures. - When constructing a new pty, allocate it's tty structure before adding it to the list. MFC after: 1 week
Diffstat (limited to 'sys/kern/tty_pts.c')
-rw-r--r--sys/kern/tty_pts.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
index 03f3e94..ff8838e 100644
--- a/sys/kern/tty_pts.c
+++ b/sys/kern/tty_pts.c
@@ -194,18 +194,16 @@ pty_new(void)
pt = LIST_FIRST(&pt_free_list);
if (pt) {
LIST_REMOVE(pt, pt_list);
- LIST_INSERT_HEAD(&pt_list, pt, pt_list);
- mtx_unlock(&pt_mtx);
} else {
nb = next_avail_nb++;
mtx_unlock(&pt_mtx);
pt = malloc(sizeof(*pt), M_PTY, M_WAITOK | M_ZERO);
+ pt->pt_tty = ttyalloc();
mtx_lock(&pt_mtx);
pt->pt_num = nb;
- LIST_INSERT_HEAD(&pt_list, pt, pt_list);
- mtx_unlock(&pt_mtx);
- pt->pt_tty = ttyalloc();
}
+ LIST_INSERT_HEAD(&pt_list, pt, pt_list);
+ mtx_unlock(&pt_mtx);
return (pt);
}
@@ -400,8 +398,16 @@ ptcopen(struct cdev *dev, int flag, int devtype, struct thread *td)
* we need to recreate it.
*/
if (pt->pt_tty == NULL) {
- pt->pt_tty = ttyalloc();
- dev->si_tty = pt->pt_tty;
+ tp = ttyalloc();
+ mtx_lock(&pt_mtx);
+ if (pt->pt_tty == NULL) {
+ pt->pt_tty = tp;
+ dev->si_tty = pt->pt_tty;
+ mtx_unlock(&pt_mtx);
+ } else {
+ mtx_unlock(&pt_mtx);
+ ttyrel(tp);
+ }
}
tp = dev->si_tty;
if (tp->t_oproc)
OpenPOWER on IntegriCloud