procfs - Fix open() for procfs.
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Thu, 24 Feb 2011 10:58:36 +0000 (11:58 +0100)
committerAntonio Huete Jimenez <tuxillo@quantumachine.net>
Thu, 24 Feb 2011 12:37:46 +0000 (13:37 +0100)
* PFIND() macro has been replaced with function pfs_pfind()
  which will hold a reference to the found proc via pfind()
  or on proc0 in the case no process is found.
* Fix a case where there was no PRELE() after a pfind()

sys/vfs/procfs/procfs.h
sys/vfs/procfs/procfs_subr.c
sys/vfs/procfs/procfs_vnops.c

index 98ea68c..071d2ab 100644 (file)
@@ -153,6 +153,8 @@ int procfs_validdbregs (struct lwp *);
 int procfs_validmap (struct lwp *);
 int procfs_validtype (struct lwp *);
 
+struct proc *pfs_pfind(pid_t);
+
 #define PROCFS_LOCKED  0x01
 #define PROCFS_WANT    0x02
 
index 44847a0..6e52dad 100644 (file)
@@ -47,6 +47,7 @@
 #include <sys/mount.h>
 #include <sys/vnode.h>
 #include <sys/malloc.h>
+#include <sys/thread2.h>
 
 #include <vfs/procfs/procfs.h>
 
@@ -255,6 +256,26 @@ procfs_freevp(struct vnode *vp)
        return (0);
 }
 
+/*
+ * Try to find the calling pid. Note that pfind()
+ * now references the proc structure to be returned
+ * and needs to be released later with PRELE().
+ */
+struct proc *
+pfs_pfind(pid_t pfs_pid)
+{
+       struct proc *p = NULL;
+
+       if (pfs_pid == 0) {
+               p = &proc0;
+               PHOLD(p);
+       } else {
+               p = pfind(pfs_pid);
+       }
+
+       return p;
+}
+
 int
 procfs_rw(struct vop_read_args *ap)
 {
@@ -274,15 +295,14 @@ procfs_rw(struct vop_read_args *ap)
 
        lwkt_gettoken(&proc_token);
 
-       p = pfind(pfs->pfs_pid);
+       p = pfs_pfind(pfs->pfs_pid);
        if (p == NULL) {
-               lwkt_reltoken(&proc_token);
-               return (EINVAL);
+               rtval = (EINVAL);
+               goto out;
        }
        if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE) {
-               lwkt_reltoken(&proc_token);
-               PRELE(p);
-               return (EACCES);
+               rtval = (EACCES);
+               goto out;
        }
        /* XXX lwp */
        lp = FIRST_LWP_IN_PROC(p);
@@ -351,7 +371,12 @@ procfs_rw(struct vop_read_args *ap)
        pfs->pfs_lockowner = 0;
        lwkt_reltoken(&proc_token);
        wakeup(&pfs->pfs_lockowner);
-       PRELE(p);
+
+out:
+       if (LWKT_TOKEN_HELD(&proc_token))
+               lwkt_reltoken(&proc_token);
+       if (p)
+               PRELE(p);
 
        return rtval;
 }
index 9ca253e..593a020 100644 (file)
@@ -174,7 +174,7 @@ procfs_open(struct vop_open_args *ap)
        struct proc *p1, *p2;
        int error;
 
-       p2 = pfind(pfs->pfs_pid);
+       p2 = pfs_pfind(pfs->pfs_pid);
        if (p2 == NULL)
                return (ENOENT);
        if (pfs->pfs_pid && !PRISON_CHECK(ap->a_cred, p2->p_ucred)) {
@@ -513,7 +513,7 @@ procfs_getattr(struct vop_getattr_args *ap)
                break;
 
        default:
-               procp = pfind(pfs->pfs_pid);
+               procp = pfs_pfind(pfs->pfs_pid);
                if (procp == NULL || procp->p_ucred == NULL) {
                        error = ENOENT;
                        goto done;
@@ -754,7 +754,7 @@ procfs_lookup(struct vop_old_lookup_args *ap)
                if (pid == NO_PID)
                        break;
 
-               p = pfind(pid);
+               p = pfs_pfind(pid);
                if (p == NULL)
                        break;
 
@@ -774,7 +774,7 @@ procfs_lookup(struct vop_old_lookup_args *ap)
                        goto out;
                }
 
-               p = pfind(pfs->pfs_pid);
+               p = pfs_pfind(pfs->pfs_pid);
                if (p == NULL)
                        break;
                /* XXX lwp */
@@ -892,7 +892,7 @@ procfs_readdir_proc(struct vop_readdir_args *ap)
        struct uio *uio = ap->a_uio;
 
        pfs = VTOPFS(ap->a_vp);
-       p = pfind(pfs->pfs_pid);
+       p = pfs_pfind(pfs->pfs_pid);
        if (p == NULL)
                return(0);
        if (!PRISON_CHECK(ap->a_cred, p->p_ucred)) {
@@ -1073,7 +1073,7 @@ procfs_readlink(struct vop_readlink_args *ap)
         * from under us...
         */
        case Pfile:
-               procp = pfind(pfs->pfs_pid);
+               procp = pfs_pfind(pfs->pfs_pid);
                if (procp == NULL || procp->p_ucred == NULL) {
                        kprintf("procfs_readlink: pid %d disappeared\n",
                            pfs->pfs_pid);