Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 30 Sep 2000 17:38:31 -0400
From:      "Brian F. Feldman" <green@FreeBSD.org>
To:        Mike Silbersack <silby@silby.com>
Cc:        "Brian F. Feldman" <green@FreeBSD.org>, security@FreeBSD.org
Subject:   Re: cvs commit: ports/mail/pine4 Makefile (fwd) 
Message-ID:  <200009302138.e8ULcW544214@green.dyndns.org>
In-Reply-To: Message from Mike Silbersack <silby@silby.com>  of "Sat, 30 Sep 2000 16:22:46 CDT." <Pine.BSF.4.21.0009301619010.23864-100000@achilles.silby.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
Mike Silbersack <silby@silby.com> wrote:
> 
> On Sat, 30 Sep 2000, Brian F. Feldman wrote:
> 
> > That is, one can create their own jail (or just chroot(8)... I should 
> > probably get user-chrooting reviewed ;) which they would use for running 
> > potentially evil things -- like reading e-mail with pine.  It's not too 
> > difficult, but it's really easier just to switch to a better MUA.
> 
> user-chrooting would be excellent.  Chrooting MUAs / web browsers / etc
> would be a nice feature no matter how secure the program in question seems
> to be.  If you get it implemented, I'll be the first to use the
> feature. :)
> 
> Mike "Silby" Silbersack

Cool :)  I use it, for example, for fuzz; it works quite nicely for that.  I 
think I have taken care of all the possible negative interactions and made 
it safe, so it does need a review, but I'm fairly sure that many people will 
want to be able to do chroot without being root.

Here's what it entails:

--- kern/kern_exec.c	2000/09/05 22:10:22	1.113
+++ kern/kern_exec.c	2000/09/15 11:41:14
@@ -280,7 +280,7 @@
 	if ((((attr.va_mode & VSUID) && p->p_ucred->cr_uid != attr.va_uid) ||
 	     ((attr.va_mode & VSGID) && p->p_ucred->cr_gid != attr.va_gid)) &&
 	    (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 &&
-	    (p->p_flag & P_TRACED) == 0) {
+	    (p->p_flag & (P_TRACED | P_UCHROOT)) == 0) {
 		/*
 		 * Turn off syscall tracing for set-id programs, except for
 		 * root.
--- kern/kern_fork.c	2000/09/05 22:10:22	1.80
+++ kern/kern_fork.c	2000/09/15 11:41:15
@@ -434,7 +434,7 @@
 	 * Preserve some more flags in subprocess.  P_PROFIL has already
 	 * been preserved.
 	 */
-	p2->p_flag |= p1->p_flag & P_SUGID;
+	p2->p_flag |= p1->p_flag & (P_SUGID | P_UCHROOT);
 	if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
 		p2->p_flag |= P_CONTROLT;
 	if (flags & RFPPWAIT)
--- kern/vfs_syscalls.c	2000/09/05 02:13:14	1.165
+++ kern/vfs_syscalls.c	2000/09/15 11:41:18
@@ -906,6 +906,21 @@
      &chroot_allow_open_directories, 0, "");
 
 /*
+ * This sysctl determines if we will allow any process to chroot(), rather
+ * than only allowing the capability for "root" users.  Once a user has
+ * performed the chroot(), there must be no way for it to gain elevated
+ * privileges, therefore P_UCHROOT is set and cannot be cleared in any
+ * way.  P_UCHROOT is used by execve() in the same manner as P_TRACE:
+ * if the user has too much control over the process, it must not gain
+ * privileges.
+ */
+
+static int chroot_allow_non_suser = 0;
+
+SYSCTL_INT(_kern, OID_AUTO, chroot_allow_non_suser, CTLFLAG_RW,
+    &chroot_allow_non_suser, 0, "");
+
+/*
  * Change notion of root (``/'') directory.
  */
 #ifndef _SYS_SYSPROTO_H_
@@ -922,12 +937,14 @@
 	} */ *uap;
 {
 	register struct filedesc *fdp = p->p_fd;
-	int error;
+	int error, notsuser;
 	struct nameidata nd;
 
 	error = suser_xxx(0, p, PRISON_ROOT);
-	if (error)
+	if (error && !chroot_allow_non_suser)
 		return (error);
+	notsuser = error;
+	error = 0;
 	if (chroot_allow_open_directories == 0 ||
 	    (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode))
 		error = chroot_refuse_vdir_fds(fdp);
@@ -944,6 +961,8 @@
 		fdp->fd_jdir = nd.ni_vp;
                 VREF(fdp->fd_jdir);
 	}
+	if (notsuser)
+		p->p_flag |= P_UCHROOT;
 	return (0);
 }
 
--- sys/proc.h	2000/09/05 22:11:12	1.110
+++ sys/proc.h	2000/09/16 12:31:49
@@ -292,6 +292,7 @@
 #define	P_JAILED	0x1000000 /* Process is in jail */
 #define	P_OLDMASK	0x2000000 /* need to restore mask before pause */
 #define	P_ALTSTACK	0x4000000 /* have alternate signal stack */
+#define	P_UCHROOT	0x8000000 /* process has performed a user-chroot */
 
 #define	P_CAN_SEE	1
 #define	P_CAN_KILL	2


--
 Brian Fundakowski Feldman           \  FreeBSD: The Power to Serve!  /
 green@FreeBSD.org                    `------------------------------'




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200009302138.e8ULcW544214>