Close two different races with concurrent opens of pty master devices
that could result in leaked ttys or a leaked pty + tty pair. MFC after: 1 week
This commit is contained in:
parent
0bc7bc0ec8
commit
0f3dd6ff0d
@ -100,6 +100,9 @@ static struct cdevsw ptc_cdevsw = {
|
||||
.d_flags = D_TTY | D_NEEDGIANT,
|
||||
};
|
||||
|
||||
static struct mtx ptyinit_lock;
|
||||
MTX_SYSINIT(ptyinit_lock, &ptyinit_lock, "ptyinit", MTX_DEF);
|
||||
|
||||
#define BUFSIZ 100 /* Chunk size iomoved to/from user */
|
||||
|
||||
struct ptsc {
|
||||
@ -151,8 +154,16 @@ ptyinit(struct cdev *devc, struct thread *td)
|
||||
|
||||
pt->pt_tty = ttyalloc();
|
||||
pt->pt_tty->t_sc = pt;
|
||||
devc->si_drv1 = pt;
|
||||
devc->si_tty = pt->pt_tty;
|
||||
mtx_lock(&ptyinit_lock);
|
||||
if (devc->si_drv1 == NULL) {
|
||||
devc->si_drv1 = pt;
|
||||
devc->si_tty = pt->pt_tty;
|
||||
mtx_unlock(&ptyinit_lock);
|
||||
} else {
|
||||
mtx_unlock(&ptyinit_lock);
|
||||
ttyrel(pt->pt_tty);
|
||||
free(pt, M_PTY);
|
||||
}
|
||||
return (devc);
|
||||
}
|
||||
|
||||
@ -335,9 +346,17 @@ 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();
|
||||
pt->pt_tty->t_sc = pt;
|
||||
dev->si_tty = pt->pt_tty;
|
||||
tp = ttyalloc();
|
||||
mtx_lock(&ptyinit_lock);
|
||||
if (pt->pt_tty == NULL) {
|
||||
pt->pt_tty = tp;
|
||||
pt->pt_tty->t_sc = pt;
|
||||
dev->si_tty = pt->pt_tty;
|
||||
mtx_unlock(&ptyinit_lock);
|
||||
} else {
|
||||
mtx_unlock(&ptyinit_lock);
|
||||
ttyrel(tp);
|
||||
}
|
||||
}
|
||||
tp = dev->si_tty;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user