From nick@milla.ask33.net  Mon Feb 10 09:08:12 2003
Return-Path: <nick@milla.ask33.net>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 02EF537B401
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 10 Feb 2003 09:08:12 -0800 (PST)
Received: from milla.ask33.net (milla.ask33.net [217.197.166.60])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 37BCC43F93
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 10 Feb 2003 09:08:11 -0800 (PST)
	(envelope-from nick@milla.ask33.net)
Received: by milla.ask33.net (Postfix, from userid 1001)
	id EB5A93ABB3B; Mon, 10 Feb 2003 18:08:00 +0100 (CET)
Message-Id: <20030210170800.EB5A93ABB3B@milla.ask33.net>
Date: Mon, 10 Feb 2003 18:08:00 +0100 (CET)
From: Pawel Jakub Dawidek <nick@garage.freebsd.pl>
Reply-To: Pawel Jakub Dawidek <nick@garage.freebsd.pl>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: Bug in procfs(5) closed in jail.
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         48156
>Category:       kern
>Synopsis:       Bug in procfs(5) closed in jail.
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    pjd
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 10 09:10:07 PST 2003
>Closed-Date:    Mon Jul 26 12:42:01 GMT 2004
>Last-Modified:  Mon Jul 26 12:42:01 GMT 2004
>Originator:     Pawel Jakub Dawidek
>Release:        FreeBSD 4.7-STABLE i386
>Organization:
cerb team
>Environment:
System: FreeBSD milla.ask33.net 4.7-STABLE FreeBSD 4.7-STABLE #12: Fri Jan 10 12:53:26 CET 2003 root@milla.ask33.net:/usr/obj/usr/src/sys/MILLA i386


>Description:
	There is a way to get list of running processes of main host
	when we are inside of jail and if procfs if mounted there.

	We can't get informations about running processes, but we can get
	their PIDs.
>How-To-Repeat:
	This simple programm shows how this works:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/jail.h>

#define	PID_MAX	99999

int
main(int argc, char *argv[])
{
	struct jail	j = { 0, "/", "test", 0 };
	char	filename[16];
	int	i;

	if (jail(&j) != 0 || chdir("/proc") != 0)
		exit(1);

	for (i = 0; i < PID_MAX; ++i) {
		snprintf(filename, sizeof(filename), "%u", i);
		if (access(filename, 0) == 0)
			printf("Process %u is running.\n", i);
	}

	exit(0);
}

>Fix:
	This patch fix this bug and fix ps_showallprocs problem too.

diff -ru procfs.orig/procfs.h procfs/procfs.h
--- procfs.orig/procfs.h	Tue Jan 22 18:22:59 2002
+++ procfs/procfs.h	Mon Feb 10 17:13:24 2003
@@ -100,6 +100,10 @@
        ((p2)->p_flag & (P_SUGID|P_INEXEC)) == 0) || \
       (suser_xxx((p1)->p_cred->pc_ucred, (p1), PRISON_ROOT) == 0))
 
+extern int	ps_showallprocs;
+#define	PROCS_CHECK(p1, p2) \
+	(PRISON_CHECK(p1, p2) && (ps_showallprocs || p_trespass(p1, p2) == 0))
+
 /*
  * Convert between pfsnode vnode
  */
diff -ru procfs.orig/procfs_vnops.c procfs/procfs_vnops.c
--- procfs.orig/procfs_vnops.c	Tue Jan 22 18:22:59 2002
+++ procfs/procfs_vnops.c	Mon Feb 10 18:02:36 2003
@@ -138,7 +138,7 @@
 	p2 = PFIND(pfs->pfs_pid);
 	if (p2 == NULL)
 		return (ENOENT);
-	if (pfs->pfs_pid && !PRISON_CHECK(ap->a_p, p2))
+	if (pfs->pfs_pid && !PROCS_CHECK(ap->a_p, p2))
 		return (ENOENT);
 
 	switch (pfs->pfs_type) {
@@ -446,6 +446,8 @@
 		if (procp == NULL || procp->p_cred == NULL ||
 		    procp->p_ucred == NULL)
 			return (ENOENT);
+		if (!PROCS_CHECK(ap->a_p, procp))
+			return (ENOENT);
 	}
 
 	error = 0;
@@ -734,6 +736,9 @@
 		if (p == NULL)
 			break;
 
+		if (!PROCS_CHECK(curproc, p))
+			break;
+
 		return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc));
 
 	case Pproc:
@@ -744,6 +749,9 @@
 		if (p == NULL)
 			break;
 
+		if (!PROCS_CHECK(curproc, p))
+			break;
+
 		for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) {
 			if (cnp->cn_namelen == pt->pt_namlen &&
 			    bcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
@@ -827,7 +835,7 @@
 		p = PFIND(pfs->pfs_pid);
 		if (p == NULL)
 			break;
-		if (!PRISON_CHECK(curproc, p))
+		if (!PROCS_CHECK(curproc, p))
 			break;
 
 		for (pt = &proc_targets[i];
@@ -890,11 +898,11 @@
 					p = p->p_list.le_next;
 					if (!p)
 						goto done;
-					if (!PRISON_CHECK(curproc, p))
+					if (!PROCS_CHECK(curproc, p))
 						continue;
 					pcnt++;
 				}
-				while (!PRISON_CHECK(curproc, p)) {
+				while (!PROCS_CHECK(curproc, p)) {
 					p = p->p_list.le_next;
 					if (!p)
 						goto done;
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->des 
Responsible-Changed-By: kris 
Responsible-Changed-When: Fri Jul 18 15:21:44 PDT 2003 
Responsible-Changed-Why:  
Assign to procfs maintainer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48156 

From: Pawel Jakub Dawidek <nick@garage.freebsd.pl>
To: FreeBSD-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: kern/48156: Bug in procfs(5) closed in jail.
Date: Mon, 28 Jul 2003 19:05:58 +0200

 --vWfgMjdKllQeoPX8
 Content-Type: text/plain; charset=iso-8859-2
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 On Mon, Feb 10, 2003 at 06:08:00PM +0100, Pawel Jakub Dawidek wrote:
 +> >Number:         48156
 +> >Category:       kern
 +> >Synopsis:       Bug in procfs(5) closed in jail.
 [...]
 +> >Release:        FreeBSD 4.7-STABLE i386
 
 This problem also exists in pseudofs implementation in FreeBSD 5.x, because
 pfs_access() function doesn't check if given file/directory is visible for
 process.
 
 This programm shows this leakage.
 
 -----[ start ]-----
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/param.h>
 #include <sys/jail.h>
 
 #define	PID_MAX	99999
 
 int
 main(void)
 {
 	struct jail j =3D { 0, "/", "test", 0 };
 	char filename[16];
 	unsigned i;
 
 	if (jail(&j) < 0 || chdir("/proc") !=3D 0)
 		exit(EXIT_FAILURE);
 
 	printf("My PID: %u\n", getpid());
 
 	for (i =3D 0; i < PID_MAX; ++i) {
 		snprintf(filename, sizeof(filename), "%u", i);
 		if (access(filename, 0777) =3D=3D 0)
 			printf("Process %u is running.\n", i);
 	}
 
 	exit(EXIT_SUCCESS);
 }
 -----[ end ]-----
 
 This patch fix it. Patch against FreeBSD 5.1-CURRENT, kern.osreldate: 50110=
 2.
 
 diff -upr /usr/src/sys/fs/pseudofs/pseudofs_vnops.c src/sys/fs/pseudofs/pse=
 udofs_vnops.c
 --- /usr/src/sys/fs/pseudofs/pseudofs_vnops.c	Tue Jul 15 01:54:02 2003
 +++ src/sys/fs/pseudofs/pseudofs_vnops.c	Tue Jul 15 01:53:44 2003
 @@ -101,10 +101,15 @@ static int
  pfs_access(struct vop_access_args *va)
  {
  	struct vnode *vn =3D va->a_vp;
 +	struct pfs_vdata *pvd =3D (struct pfs_vdata *)vn->v_data;
 +	struct pfs_node *pn =3D pvd->pvd_pn;
  	struct vattr vattr;
  	int error;
 =20
  	PFS_TRACE((((struct pfs_vdata *)vn->v_data)->pvd_pn->pn_name));
 +
 +	if (!pfs_visible(va->a_td, pn, pvd->pvd_pid))
 +		PFS_RETURN (ENOENT);
 =20
  	error =3D VOP_GETATTR(vn, &vattr, va->a_cred, va->a_td);
  	if (error)
 
 --=20
 Pawel Jakub Dawidek                       pawel@dawidek.net
 UNIX Systems Programmer/Administrator     http://garage.freebsd.pl
 Am I Evil? Yes, I Am!                     http://cerber.sourceforge.net
 
 --vWfgMjdKllQeoPX8
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.0.7 (FreeBSD)
 
 iQCVAwUBPyVX9j/PhmMH/Mf1AQGzEgQAme1aYJrmCssKgQJIsCxhI26cZ9fFcjdj
 8UysTV+xYV0+VtfYn5J6IgnZgd0X+pWHW7glmqKUoOchnlw7iWSRU3mwOUfT2gMP
 HxDURtfEMV72bQYCNOqYdWsuPOMDaSR0UZ5TPSRU+76MhL8qre9zseugkr42JW9W
 Ljw2gXuP2cA=
 =5eXy
 -----END PGP SIGNATURE-----
 
 --vWfgMjdKllQeoPX8--
State-Changed-From-To: open->analyzed 
State-Changed-By: des 
State-Changed-When: Tue Aug 19 03:26:54 PDT 2003 
State-Changed-Why:  
The problem is easily reproducable and the patch seems correct. 


Responsible-Changed-From-To: des->freebsd-bugs 
Responsible-Changed-By: des 
Responsible-Changed-When: Tue Aug 19 03:26:54 PDT 2003 
Responsible-Changed-Why:  
I have fixed pseudofs in -CURRENT, but have neither the time nor the 
inclination to fix procfs / linprocfs in -STABLE. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48156 
State-Changed-From-To: analyzed->open 
State-Changed-By: maxim 
State-Changed-When: Sat May 29 23:59:21 PDT 2004 
State-Changed-Why:  
Hard to believe freebsd-bugs is analizing this PR. 


Responsible-Changed-From-To: freebsd-bugs->pjd 
Responsible-Changed-By: maxim 
Responsible-Changed-When: Sat May 29 23:59:21 PDT 2004 
Responsible-Changed-Why:  
Pawel has a commit bit now. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48156 
State-Changed-From-To: open->closed 
State-Changed-By: pjd 
State-Changed-When: Mon Jul 26 12:39:14 GMT 2004 
State-Changed-Why:  
Problem doesn't exist in -CURRENT. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=48156 
>Unformatted:
