Module Name: src Committed By: kamil Date: Fri May 31 23:01:39 UTC 2019
Modified Files: src/sys/kern: kern_proc.c src/sys/sys: sysctl.h Log Message: Implement KERN_PROC_CWD in sysctl(3) Retrieve specified process current working directory. Fixes PR kern/50620 by Thomas Klausner. To generate a diff of this commit: cvs rdiff -u -r1.228 -r1.229 src/sys/kern/kern_proc.c cvs rdiff -u -r1.229 -r1.230 src/sys/sys/sysctl.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_proc.c diff -u src/sys/kern/kern_proc.c:1.228 src/sys/kern/kern_proc.c:1.229 --- src/sys/kern/kern_proc.c:1.228 Fri Mar 1 11:06:57 2019 +++ src/sys/kern/kern_proc.c Fri May 31 23:01:39 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_proc.c,v 1.228 2019/03/01 11:06:57 pgoyette Exp $ */ +/* $NetBSD: kern_proc.c,v 1.229 2019/05/31 23:01:39 kamil 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.228 2019/03/01 11:06:57 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.229 2019/05/31 23:01:39 kamil Exp $"); #ifdef _KERNEL_OPT #include "opt_kstack.h" @@ -246,6 +246,7 @@ static kauth_listener_t proc_listener; static void fill_proc(const struct proc *, struct proc *, bool); static int fill_pathname(struct lwp *, pid_t, void *, size_t *); +static int fill_cwd(struct lwp *, pid_t, void *, size_t *); static int proc_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, @@ -1945,6 +1946,12 @@ sysctl_kern_proc_args(SYSCTLFN_ARGS) sysctl_relock(); return error; + case KERN_PROC_CWD: + sysctl_unlock(); + error = fill_cwd(l, pid, oldp, oldlenp); + sysctl_relock(); + return error; + case KERN_PROC_ARGV: case KERN_PROC_NARGV: case KERN_PROC_ENV: @@ -2577,6 +2584,58 @@ fill_pathname(struct lwp *l, pid_t pid, return error; } +static int +fill_cwd(struct lwp *l, pid_t pid, void *oldp, size_t *oldlenp) +{ + int error; + struct proc *p; + char *path; + char *bp, *bend; + struct cwdinfo *cwdi; + struct vnode *vp; + size_t len, lenused; + const int flags = GETCWD_CHECK_ACCESS; + + if ((error = proc_find_locked(l, &p, pid)) != 0) + return error; + + len = MAXPATHLEN * 4; + if (*oldlenp < 2) { + if (pid != -1) + mutex_exit(p->p_lock); + return ERANGE; + } + + path = kmem_alloc(len, KM_SLEEP); + + bp = &path[len]; + bend = bp; + *(--bp) = '\0'; + + cwdi = p->p_cwdi; + rw_enter(&cwdi->cwdi_lock, RW_READER); + vp = cwdi->cwdi_cdir; + error = getcwd_common(vp, NULL, &bp, path, len/2, flags, l); + rw_exit(&cwdi->cwdi_lock); + + if (error) + goto out; + + lenused = bend - bp; + + if (oldp != NULL) { + error = sysctl_copyout(l, bp, oldp, lenused); + if (error == 0 && *oldlenp < lenused) + error = ENOSPC; + } + *oldlenp = lenused; +out: + if (pid != -1) + mutex_exit(p->p_lock); + kmem_free(path, len); + return error; +} + int proc_getauxv(struct proc *p, void **buf, size_t *len) { Index: src/sys/sys/sysctl.h diff -u src/sys/sys/sysctl.h:1.229 src/sys/sys/sysctl.h:1.230 --- src/sys/sys/sysctl.h:1.229 Wed Dec 5 18:16:51 2018 +++ src/sys/sys/sysctl.h Fri May 31 23:01:39 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sysctl.h,v 1.229 2018/12/05 18:16:51 christos Exp $ */ +/* $NetBSD: sysctl.h,v 1.230 2019/05/31 23:01:39 kamil Exp $ */ /* * Copyright (c) 1989, 1993 @@ -585,6 +585,7 @@ struct kinfo_lwp { #define KERN_PROC_ENV 3 /* environ */ #define KERN_PROC_NENV 4 /* number of strings in above */ #define KERN_PROC_PATHNAME 5 /* path to executable */ +#define KERN_PROC_CWD 6 /* current working dir */ /* * KERN_SYSVIPC subtypes