[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fchroot/chroot



the attached patch implements fchroot, slightly adapted from netbsd.
also, shouldn't there be another VREF() in sys_chroot(), since we might
be using the vnode as cdir _and_ rdir ?

-p.
Index: sys/kern/init_sysent.c
===================================================================
RCS file: /cvs/src/sys/kern/init_sysent.c,v
retrieving revision 1.76
diff -u -r1.76 init_sysent.c
--- sys/kern/init_sysent.c	2004/02/28 19:44:30	1.76
+++ sys/kern/init_sysent.c	2004/03/08 15:28:25
@@ -1,4 +1,4 @@
-/*	$OpenBSD: init_sysent.c,v 1.76 2004/02/28 19:44:30 miod Exp $	*/
+/*	$OpenBSD$	*/
 
 /*
  * System call switch table.
@@ -756,5 +756,7 @@
 	    sys_closefrom },			/* 287 = closefrom */
 	{ 2, s(struct sys_sigaltstack_args),
 	    sys_sigaltstack },			/* 288 = sigaltstack */
+	{ 1, s(struct sys_fchroot_args),
+	    sys_fchroot },			/* 289 = fchroot */
 };
 
Index: sys/kern/syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/syscalls.c,v
retrieving revision 1.76
diff -u -r1.76 syscalls.c
--- sys/kern/syscalls.c	2004/02/28 19:44:30	1.76
+++ sys/kern/syscalls.c	2004/03/08 15:28:27
@@ -1,4 +1,4 @@
-/*	$OpenBSD: syscalls.c,v 1.76 2004/02/28 19:44:30 miod Exp $	*/
+/*	$OpenBSD$	*/
 
 /*
  * System call names.
@@ -384,4 +384,5 @@
 	"mquery",			/* 286 = mquery */
 	"closefrom",			/* 287 = closefrom */
 	"sigaltstack",			/* 288 = sigaltstack */
+	"fchroot",			/* 289 = fchroot */
 };
Index: sys/kern/syscalls.master
===================================================================
RCS file: /cvs/src/sys/kern/syscalls.master,v
retrieving revision 1.68
diff -u -r1.68 syscalls.master
--- sys/kern/syscalls.master	2004/02/28 19:44:16	1.68
+++ sys/kern/syscalls.master	2004/03/08 15:28:29
@@ -575,3 +575,4 @@
 287	STD		{ int sys_closefrom(int fd); }			    
 288	STD		{ int sys_sigaltstack(const struct sigaltstack *nss, \
 			    struct sigaltstack *oss); }
+289	STD		{ int sys_fchroot(int fd); }
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.108
diff -u -r1.108 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c	2004/01/06 04:18:18	1.108
+++ sys/kern/vfs_syscalls.c	2004/03/08 15:28:34
@@ -829,6 +829,9 @@
 	    SCARG(uap, path), p);
 	if ((error = change_dir(&nd, p)) != 0)
 		return (error);
+
+        VREF(nd.ni_vp);
+
 	if (fdp->fd_rdir != NULL) {
 		/*
 		 * A chroot() done inside a changed root environment does
@@ -841,6 +844,56 @@
 	}
 	fdp->fd_rdir = nd.ni_vp;
 	return (0);
+}
+
+/*
+ * Change notion of root (``/'') directory to a file descriptor.
+ */
+int
+sys_fchroot(p, v, retval)
+	struct proc *p;
+	void *v;
+	register_t *retval;
+{
+	struct sys_fchroot_args *uap = v;
+	struct filedesc *fdp = p->p_fd;
+	struct vnode *vp;
+	struct file *fp;
+	int error;
+
+	if ((error = suser(p, 0)) != 0)
+		return (error);
+        if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
+                return (error);
+
+        vp = (struct vnode *)fp->f_data;
+        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+
+        if (vp->v_type != VDIR)
+                error = ENOTDIR;
+        else
+                error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
+
+        VOP_UNLOCK(vp, 0, p);
+
+        if (error)
+		return (error);
+
+        VREF(vp);
+
+	if (fdp->fd_rdir != NULL) {
+		/*
+		 * A chroot() done inside a changed root environment does
+		 * an automatic chdir to avoid the out-of-tree experience.
+		 */
+		vrele(fdp->fd_rdir);
+		vrele(fdp->fd_cdir);
+		VREF(vp);
+		fdp->fd_cdir = vp;
+        }
+	
+        fdp->fd_rdir = vp;
+        return (0);
 }
 
 /*
Index: lib/libc/sys/Makefile.inc
===================================================================
RCS file: /cvs/src/lib/libc/sys/Makefile.inc,v
retrieving revision 1.69
diff -u -r1.69 Makefile.inc
--- lib/libc/sys/Makefile.inc	2004/02/13 22:15:29	1.69
+++ lib/libc/sys/Makefile.inc	2004/03/08 15:28:42
@@ -32,8 +32,8 @@
 ASM=	accept.o access.o acct.o adjtime.o bind.o chdir.o chflags.o chmod.o \
 	chown.o chroot.o clock_gettime.o clock_settime.o clock_getres.o \
 	close.o closefrom.o connect.o dup.o dup2.o execve.o fchdir.o \
-	fchflags.o fchmod.o fchown.o fcntl.o fhopen.o fhstat.o fhstatfs.o \
-	flock.o fpathconf.o fstat.o \
+	fchflags.o fchmod.o fchown.o fchroot.o fcntl.o fhopen.o fhstat.o \
+	fhstatfs.o flock.o fpathconf.o fstat.o \
 	fstatfs.o fsync.o futimes.o getdirentries.o getegid.o geteuid.o \
 	getfh.o getfsstat.o getgid.o getgroups.o getitimer.o getpeereid.o \
 	getpeername.o \