procfs patch (fwd)

Alex (garbanzo@hooked.net)
Mon, 11 Aug 1997 11:17:27 -0700

My mistake it was on the freebsd-current list, not freebsd-hackers list.
This is for 3.0-CURRENT, but could probably adapted to 2.2 or lower.

---------- Forwarded message ----------
Date: Sun, 10 Aug 1997 20:15:52 -0700 (PDT)
From: Sean Eric Fagan <sef@FreeBSD.ORG>
To: current@FreeBSD.ORG, security@FreeBSD.ORG
Subject: procfs patch

The following patch should fix the problem with procfs. These patches
are to -current (well, a version I just checked out about an hour
ago). I have 2.2-GAMMA diffs as well.

Index: miscfs/procfs/procfs.h
===================================================================
RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs.h,v
retrieving revision 1.15
diff -u -r1.15 procfs.h
--- procfs.h 1997/02/22 09:40:26 1.15
+++ procfs.h 1997/08/11 01:42:06
@@ -85,6 +85,18 @@
(bcmp((s), (cnp)->cn_nameptr, (len)) == 0))

#define KMEM_GROUP 2
+
+/*
+ * Check to see whether access to target process is allowed
+ * Evaluates to 1 if access is allowed.
+ */
+#define CHECKIO(p1, p2) \
+ ((((p1)->p_cred->pc_ucred->cr_uid == (p2)->p_cred->p_ruid) && \
+ ((p1)->p_cred->p_ruid == (p2)->p_cred->p_ruid) && \
+ ((p1)->p_cred->p_svuid == (p2)->p_cred->p_ruid) && \
+ ((p2)->p_flag & P_SUGID) == 0) || \
+ (suser((p1)->p_cred->pc_ucred, &(p1)->p_acflag) == 0))
+
/*
* Format of a directory entry in /proc, ...
* This must map onto struct dirent (see <dirent.h>)
Index: miscfs/procfs/procfs_mem.c
===================================================================
RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_mem.c,v
retrieving revision 1.26
diff -u -r1.26 procfs_mem.c
--- procfs_mem.c 1997/08/02 14:32:14 1.26
+++ procfs_mem.c 1997/08/11 01:44:26
@@ -277,6 +277,23 @@
if (uio->uio_resid == 0)
return (0);

+ /*
+ * XXX
+ * We need to check for KMEM_GROUP because ps is sgid kmem;
+ * not allowing it here causes ps to not work properly. Arguably,
+ * this is a bug with what ps does. We only need to do this
+ * for Pmem nodes, and only if it's reading. This is still not
+ * good, as it may still be possible to grab illicit data if
+ * a process somehow gets to be KMEM_GROUP. Note that this also
+ * means that KMEM_GROUP can't change without editing procfs.h!
+ * All in all, quite yucky.
+ */
+
+ if (!CHECKIO(curp, p) &&
+ ((curp->p_cred->pc_ucred->cr_gid != KMEM_GROUP) &&
+ (uio->uio_rw != UIO_READ))
+ return EPERM;
+
return (procfs_rwmem(p, uio));
}

Index: miscfs/procfs/procfs_regs.c
===================================================================
RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_regs.c,v
retrieving revision 1.7
diff -u -r1.7 procfs_regs.c
--- procfs_regs.c 1997/08/02 14:32:16 1.7
+++ procfs_regs.c 1997/08/11 01:42:06
@@ -60,6 +60,8 @@
char *kv;
int kl;

+ if (!CHECKIO(curp, p))
+ return EPERM;
kl = sizeof(r);
kv = (char *) &r;

Index: miscfs/procfs/procfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_vnops.c,v
retrieving revision 1.30
diff -u -r1.30 procfs_vnops.c
--- procfs_vnops.c 1997/08/02 14:32:20 1.30
+++ procfs_vnops.c 1997/08/11 01:43:41
@@ -127,16 +127,21 @@
} */ *ap;
{
struct pfsnode *pfs = VTOPFS(ap->a_vp);
+ struct proc *p1 = ap->a_p, *p2 = PFIND(pfs->pfs_pid);
+
+ if (p2 == NULL)
+ return ENOENT;

switch (pfs->pfs_type) {
case Pmem:
- if (PFIND(pfs->pfs_pid) == 0)
- return (ENOENT); /* was ESRCH, jsp */
-
if ((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL) ||
(pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))
return (EBUSY);

+ if (!CHECKIO(p1, p2) &&
+ (p1->p_cred->pc_ucred->cr_gid != KMEM_GROUP))
+ return EPERM;
+
if (ap->a_mode & FWRITE)
pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);

@@ -194,7 +199,6 @@
struct proc *a_p;
} */ *ap;
{
-
return (ENOTTY);
}