git: d4380c0cdd05 - main - jail: Change both root and working directories in jail_attach(2)

Jamie Gritton jamie at FreeBSD.org
Fri Feb 19 22:13:50 UTC 2021


The branch main has been updated by jamie:

URL: https://cgit.FreeBSD.org/src/commit/?id=d4380c0cdd0517dc038403dd5c99242ce78bdeb5

commit d4380c0cdd0517dc038403dd5c99242ce78bdeb5
Author:     Jamie Gritton <jamie at FreeBSD.org>
AuthorDate: 2021-02-19 22:13:35 +0000
Commit:     Jamie Gritton <jamie at FreeBSD.org>
CommitDate: 2021-02-19 22:13:35 +0000

    jail: Change both root and working directories in jail_attach(2)
    
    jail_attach(2) performs an internal chroot operation, leaving it up to
    the calling process to assure the working directory is inside the jail.
    
    Add a matching internal chdir operation to the jail's root.  Also
    ignore kern.chroot_allow_open_directories, and always disallow the
    operation if there are any directory descriptors open.
    
    Reported by:    mjg
    Approved by:    markj, kib
    MFC after:      3 days
---
 lib/libc/sys/jail.2     |  5 ++++-
 sys/kern/kern_descrip.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 sys/kern/kern_jail.c    |  2 +-
 sys/sys/filedesc.h      |  1 +
 4 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/lib/libc/sys/jail.2 b/lib/libc/sys/jail.2
index 2e13a6c3a381..82c2e97d4a7b 100644
--- a/lib/libc/sys/jail.2
+++ b/lib/libc/sys/jail.2
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 8, 2012
+.Dd February 19, 2021
 .Dt JAIL 2
 .Os
 .Sh NAME
@@ -228,6 +228,9 @@ The
 system call attaches the current process to an existing jail,
 identified by
 .Fa jid .
+It changes the process's root and current directories to the jail's
+.Va path
+directory.
 .Pp
 The
 .Fn jail_remove
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 43cedfe2199b..0813b6c8f3b8 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -3795,9 +3795,8 @@ pwd_drop(struct pwd *pwd)
 }
 
 /*
-* Common routine for kern_chroot() and jail_attach().  The caller is
-* responsible for invoking priv_check() and mac_vnode_check_chroot() to
-* authorize this operation.
+* The caller is responsible for invoking priv_check() and
+* mac_vnode_check_chroot() to authorize this operation.
 */
 int
 pwd_chroot(struct thread *td, struct vnode *vp)
@@ -3859,6 +3858,46 @@ pwd_chdir(struct thread *td, struct vnode *vp)
 	pwd_drop(oldpwd);
 }
 
+/*
+ * jail_attach(2) changes both root and working directories.
+ */
+int
+pwd_chroot_chdir(struct thread *td, struct vnode *vp)
+{
+	struct pwddesc *pdp;
+	struct filedesc *fdp;
+	struct pwd *newpwd, *oldpwd;
+	int error;
+
+	fdp = td->td_proc->p_fd;
+	pdp = td->td_proc->p_pd;
+	newpwd = pwd_alloc();
+	FILEDESC_SLOCK(fdp);
+	PWDDESC_XLOCK(pdp);
+	oldpwd = PWDDESC_XLOCKED_LOAD_PWD(pdp);
+	error = chroot_refuse_vdir_fds(fdp);
+	FILEDESC_SUNLOCK(fdp);
+	if (error != 0) {
+		PWDDESC_XUNLOCK(pdp);
+		pwd_drop(newpwd);
+		return (error);
+	}
+
+	vrefact(vp);
+	newpwd->pwd_rdir = vp;
+	vrefact(vp);
+	newpwd->pwd_cdir = vp;
+	if (oldpwd->pwd_jdir == NULL) {
+		vrefact(vp);
+		newpwd->pwd_jdir = vp;
+	}
+	pwd_fill(oldpwd, newpwd);
+	pwd_set(pdp, newpwd);
+	PWDDESC_XUNLOCK(pdp);
+	pwd_drop(oldpwd);
+	return (0);
+}
+
 void
 pwd_ensure_dirs(void)
 {
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index b56c889eeb7e..90ab69a372d2 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -2495,7 +2495,7 @@ do_jail_attach(struct thread *td, struct prison *pr)
 		goto e_unlock;
 #endif
 	VOP_UNLOCK(pr->pr_root);
-	if ((error = pwd_chroot(td, pr->pr_root)))
+	if ((error = pwd_chroot_chdir(td, pr->pr_root)))
 		goto e_revert_osd;
 
 	newcred = crget();
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index 890232b7f160..8c5aa258ed28 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -333,6 +333,7 @@ void	pdunshare(struct thread *td);
 
 void	pwd_chdir(struct thread *td, struct vnode *vp);
 int	pwd_chroot(struct thread *td, struct vnode *vp);
+int	pwd_chroot_chdir(struct thread *td, struct vnode *vp);
 void	pwd_ensure_dirs(void);
 void	pwd_set_rootvnode(void);
 


More information about the dev-commits-src-main mailing list