Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern implementation of KERN_PROC_PATHNAME, some refactor...



details:   https://anonhg.NetBSD.org/src/rev/bb02a570a3c9
branches:  trunk
changeset: 340673:bb02a570a3c9
user:      christos <christos%NetBSD.org@localhost>
date:      Thu Sep 24 14:33:01 2015 +0000

description:
implementation of KERN_PROC_PATHNAME, some refactoring for KERN_PROC.

diffstat:

 sys/kern/kern_proc.c |  106 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 97 insertions(+), 9 deletions(-)

diffs (163 lines):

diff -r a5e6f68b440b -r bb02a570a3c9 sys/kern/kern_proc.c
--- a/sys/kern/kern_proc.c      Thu Sep 24 14:32:15 2015 +0000
+++ b/sys/kern/kern_proc.c      Thu Sep 24 14:33:01 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_proc.c,v 1.193 2014/07/12 09:57:25 njoly Exp $    */
+/*     $NetBSD: kern_proc.c,v 1.194 2015/09/24 14:33:01 christos Exp $ */
 
 /*-
  * Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.193 2014/07/12 09:57:25 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.194 2015/09/24 14:33:01 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_kstack.h"
@@ -95,12 +95,14 @@
 #include <sys/sleepq.h>
 #include <sys/atomic.h>
 #include <sys/kmem.h>
+#include <sys/namei.h>
 #include <sys/dtrace_bsd.h>
 #include <sys/sysctl.h>
 #include <sys/exec.h>
 #include <sys/cpu.h>
 
 #include <uvm/uvm_extern.h>
+#include <uvm/uvm.h>
 
 #ifdef COMPAT_NETBSD32
 #include <compat/netbsd32/netbsd32.h>
@@ -234,6 +236,8 @@
 
 static kauth_listener_t proc_listener;
 
+static int fill_pathname(struct lwp *, pid_t, void *, size_t *);
+
 static int
 proc_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
     void *arg0, void *arg1, void *arg2, void *arg3)
@@ -1633,18 +1637,25 @@
        type = rnode->sysctl_num;
 
        if (type == KERN_PROC) {
-               if (namelen != 2 && !(namelen == 1 && name[0] == KERN_PROC_ALL))
-                       return (EINVAL);
-               op = name[0];
-               if (op != KERN_PROC_ALL)
+               if (namelen == 0)
+                       return EINVAL;
+               switch (op = name[0]) {
+               case KERN_PROC_ALL:
+                       if (namelen != 1)
+                               return EINVAL;
+                       arg = 0;
+                       break;
+               default:
+                       if (namelen != 2)
+                               return EINVAL;
                        arg = name[1];
-               else
-                       arg = 0;                /* Quell compiler warning */
+                       break;
+               }
                elem_count = 0; /* Ditto */
                kelem_size = elem_size = sizeof(kbuf->kproc);
        } else {
                if (namelen != 4)
-                       return (EINVAL);
+                       return EINVAL;
                op = name[0];
                arg = name[1];
                elem_size = name[2];
@@ -1893,6 +1904,12 @@
        type = name[1];
 
        switch (type) {
+       case KERN_PROC_PATHNAME:
+               sysctl_unlock();
+               error = fill_pathname(l, pid, oldp, oldlenp);
+               sysctl_relock();
+               return error;
+
        case KERN_PROC_ARGV:
        case KERN_PROC_NARGV:
        case KERN_PROC_ENV:
@@ -2386,3 +2403,74 @@
                ki->p_uctime_usec = ut.tv_usec;
        }
 }
+
+
+int
+proc_find_locked(struct lwp *l, struct proc **p, pid_t pid)
+{
+       int error;
+
+       mutex_enter(proc_lock);
+       if (pid == -1)
+               *p = l->l_proc;
+       else
+               *p = proc_find(pid);
+
+       if (*p == NULL) {
+               if (pid != -1)
+                       mutex_exit(proc_lock);
+               return ESRCH;
+       }
+       if (pid != -1)
+               mutex_enter((*p)->p_lock);
+       mutex_exit(proc_lock);
+
+       error = kauth_authorize_process(l->l_cred,
+           KAUTH_PROCESS_CANSEE, *p,
+           KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
+       if (error) {
+               if (pid != -1)
+                       mutex_exit((*p)->p_lock);
+       }
+       return error;
+}
+
+static int
+fill_pathname(struct lwp *l, pid_t pid, void *oldp, size_t *oldlenp)
+{
+#ifndef _RUMPKERNEL
+       int error;
+       struct proc *p;
+       char *path;
+       size_t len;
+
+       if ((error = proc_find_locked(l, &p, pid)) != 0)
+               return error;
+
+       if (p->p_textvp == NULL) {
+               if (pid != -1)
+                       mutex_exit(p->p_lock);
+               return ENOENT;
+       }
+
+       path = PNBUF_GET();
+       error = vnode_to_path(path, MAXPATHLEN / 2, p->p_textvp, l, p);
+       if (error)
+               goto out;
+
+       len = strlen(path) + 1;
+       if (oldp != NULL) {
+               error = sysctl_copyout(l, path, oldp, *oldlenp);
+               if (error == 0 && *oldlenp < len)
+                       error = ENOSPC;
+       }
+       *oldlenp = len;
+out:
+       PNBUF_PUT(path);
+       if (pid != -1)
+               mutex_exit(p->p_lock);
+       return error;
+#else
+       return 0;
+#endif
+}



Home | Main Index | Thread Index | Old Index