mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Improve nested jail awareness of devfs by handling credentials.
Now that we start to use credentials on character devices more often (because of MPSAFE TTY), move the prison-checks that are in place in the TTY code into devfs. Instead of strictly comparing the prisons, use the more common prison_check() function to compare credentials. This means that pseudo-terminals are only visible in devfs by processes within the same jail and parent jails. Even though regular users in parent jails can now interact with pseudo-terminals from child jails, this seems to be the right approach. These processes are also capable of interacting with the jailed processes anyway, through signals for example. Reviewed by: kib, rwatson (older version)
This commit is contained in:
parent
6c3154f6a1
commit
f8f6146082
3 changed files with 22 additions and 8 deletions
|
|
@ -48,6 +48,7 @@
|
|||
#include <sys/file.h>
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
|
|
@ -706,6 +707,22 @@ devfs_kqfilter_f(struct file *fp, struct knote *kn)
|
|||
return (error);
|
||||
}
|
||||
|
||||
static inline int
|
||||
devfs_prison_check(struct devfs_dirent *de, struct ucred *tcr)
|
||||
{
|
||||
struct cdev_priv *cdp;
|
||||
struct ucred *dcr;
|
||||
|
||||
cdp = de->de_cdp;
|
||||
if (cdp == NULL)
|
||||
return (0);
|
||||
dcr = cdp->cdp_c.si_cred;
|
||||
if (dcr == NULL)
|
||||
return (0);
|
||||
|
||||
return (prison_check(tcr, dcr));
|
||||
}
|
||||
|
||||
static int
|
||||
devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
|
||||
{
|
||||
|
|
@ -831,6 +848,9 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
|
|||
return (ENOENT);
|
||||
}
|
||||
|
||||
if (devfs_prison_check(de, td->td_ucred))
|
||||
return (ENOENT);
|
||||
|
||||
if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) {
|
||||
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
|
||||
if (error)
|
||||
|
|
@ -1106,6 +1126,8 @@ 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))
|
||||
continue;
|
||||
if (dd->de_dirent->d_type == DT_DIR)
|
||||
de = dd->de_dir;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -219,13 +219,6 @@ ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
|
|||
struct tty *tp = dev->si_drv1;
|
||||
int error = 0;
|
||||
|
||||
/* Disallow access when the TTY belongs to a different prison. */
|
||||
if (dev->si_cred != NULL &&
|
||||
dev->si_cred->cr_prison != td->td_ucred->cr_prison &&
|
||||
priv_check(td, PRIV_TTY_PRISON)) {
|
||||
return (EPERM);
|
||||
}
|
||||
|
||||
tty_lock(tp);
|
||||
if (tty_gone(tp)) {
|
||||
/* Device is already gone. */
|
||||
|
|
|
|||
|
|
@ -211,7 +211,6 @@
|
|||
#define PRIV_TTY_DRAINWAIT 251 /* Set tty drain wait time. */
|
||||
#define PRIV_TTY_DTRWAIT 252 /* Set DTR wait on tty. */
|
||||
#define PRIV_TTY_EXCLUSIVE 253 /* Override tty exclusive flag. */
|
||||
#define PRIV_TTY_PRISON 254 /* Can open pts across jails. */
|
||||
#define PRIV_TTY_STI 255 /* Simulate input on another tty. */
|
||||
#define PRIV_TTY_SETA 256 /* Set tty termios structure. */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue