Bugtraq mailing list archives

procfs patch (fwd)


From: garbanzo () hooked net (Alex)
Date: 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);
 }



Current thread: