summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/fs/devfs/devfs_vnops.c25
-rw-r--r--sys/kern/kern_exit.c1
-rw-r--r--sys/kern/kern_proc.c1
-rw-r--r--sys/sys/proc.h1
4 files changed, 21 insertions, 7 deletions
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 3d6e0f0..4c059cd 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -436,14 +436,14 @@ devfs_access(struct vop_access_args *ap)
error = vaccess(vp->v_type, de->de_mode, de->de_uid, de->de_gid,
ap->a_accmode, ap->a_cred, NULL);
- if (!error)
- return (error);
+ if (error == 0)
+ return (0);
if (error != EACCES)
return (error);
/* We do, however, allow access to the controlling terminal */
if (!(ap->a_td->td_proc->p_flag & P_CONTROLT))
return (error);
- if (ap->a_td->td_proc->p_session->s_ttyvp == de->de_vnode)
+ if (ap->a_td->td_proc->p_session->s_ttydp == de->de_cdp)
return (0);
return (error);
}
@@ -474,6 +474,7 @@ devfs_close(struct vop_close_args *ap)
VI_LOCK(vp);
if (count_dev(dev) == 2 && (vp->v_iflag & VI_DOOMED) == 0) {
td->td_proc->p_session->s_ttyvp = NULL;
+ td->td_proc->p_session->s_ttydp = NULL;
oldvp = vp;
}
VI_UNLOCK(vp);
@@ -675,6 +676,7 @@ devfs_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred, struc
VREF(vp);
SESS_LOCK(td->td_proc->p_session);
td->td_proc->p_session->s_ttyvp = vp;
+ td->td_proc->p_session->s_ttydp = cdev2priv(dev);
SESS_UNLOCK(td->td_proc->p_session);
sx_sunlock(&proctree_lock);
@@ -708,10 +710,11 @@ devfs_kqfilter_f(struct file *fp, struct knote *kn)
}
static inline int
-devfs_prison_check(struct devfs_dirent *de, struct ucred *tcr)
+devfs_prison_check(struct devfs_dirent *de, struct thread *td)
{
struct cdev_priv *cdp;
struct ucred *dcr;
+ int error;
cdp = de->de_cdp;
if (cdp == NULL)
@@ -720,7 +723,15 @@ devfs_prison_check(struct devfs_dirent *de, struct ucred *tcr)
if (dcr == NULL)
return (0);
- return (prison_check(tcr, dcr));
+ error = prison_check(td->td_ucred, dcr);
+ if (error == 0)
+ return (0);
+ /* We do, however, allow access to the controlling terminal */
+ if (!(td->td_proc->p_flag & P_CONTROLT))
+ return (error);
+ if (td->td_proc->p_session->s_ttydp == cdp)
+ return (0);
+ return (error);
}
static int
@@ -848,7 +859,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
return (ENOENT);
}
- if (devfs_prison_check(de, td->td_ucred))
+ if (devfs_prison_check(de, td))
return (ENOENT);
if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) {
@@ -1126,7 +1137,7 @@ devfs_readdir(struct vop_readdir_args *ap)
KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__));
if (dd->de_flags & DE_WHITEOUT)
continue;
- if (devfs_prison_check(dd, ap->a_cred))
+ if (devfs_prison_check(dd, uio->uio_td))
continue;
if (dd->de_dirent->d_type == DT_DIR)
de = dd->de_dir;
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index b96cdbf..af00f42 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -316,6 +316,7 @@ exit1(struct thread *td, int rv)
ttyvp = sp->s_ttyvp;
tp = sp->s_ttyp;
sp->s_ttyvp = NULL;
+ sp->s_ttydp = NULL;
sp->s_leader = NULL;
SESS_UNLOCK(sp);
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index f931245..86eb6fc 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -358,6 +358,7 @@ enterpgrp(p, pgid, pgrp, sess)
sess->s_sid = p->p_pid;
refcount_init(&sess->s_count, 1);
sess->s_ttyvp = NULL;
+ sess->s_ttydp = NULL;
sess->s_ttyp = NULL;
bcopy(p->p_session->s_login, sess->s_login,
sizeof(sess->s_login));
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 3eb6ea6..d8e9fc8 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -77,6 +77,7 @@ struct session {
u_int s_count; /* Ref cnt; pgrps in session - atomic. */
struct proc *s_leader; /* (m + e) Session leader. */
struct vnode *s_ttyvp; /* (m) Vnode of controlling tty. */
+ struct cdev_priv *s_ttydp; /* (m) Device of controlling tty. */
struct tty *s_ttyp; /* (e) Controlling tty. */
pid_t s_sid; /* (c) Session ID. */
/* (m) Setlogin() name: */
OpenPOWER on IntegriCloud