Index: sys/kern/kern_proc.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_proc.c,v retrieving revision 1.228 diff -u -r1.228 kern_proc.c --- sys/kern/kern_proc.c 1 Mar 2019 11:06:57 -0000 1.228 +++ sys/kern/kern_proc.c 31 May 2019 21:43:32 -0000 @@ -1945,6 +1945,12 @@ 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 +2583,56 @@ 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; + size_t len, lenused; + + 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); + error = getcwd_common(cwdi->cwdi_cdir, NULL, &bp, path, + len/2, GETCWD_CHECK_ACCESS, l); + rw_exit(&cwdi->cwdi_lock); + + if (error) + goto out; + + lenused = bend - bp; + + if (oldp != NULL) { + error = sysctl_copyout(l, path, 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) {