diff options
-rw-r--r-- | lib/libc/gen/sysctl.3 | 9 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 68 | ||||
-rw-r--r-- | sys/kern/vfs_getcwd.c | 4 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 6 | ||||
-rw-r--r-- | sys/sys/vnode.h | 3 |
5 files changed, 81 insertions, 9 deletions
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3 index 0c0f7090c94..e9bed504790 100644 --- a/lib/libc/gen/sysctl.3 +++ b/lib/libc/gen/sysctl.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sysctl.3,v 1.209 2011/09/25 17:48:17 jmc Exp $ +.\" $OpenBSD: sysctl.3,v 1.210 2011/12/09 16:14:54 nicm Exp $ .\" .\" Copyright (c) 1993 .\" The Regents of the University of California. All rights reserved. @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd $Mdocdate: September 25 2011 $ +.Dd $Mdocdate: December 9 2011 $ .Dt SYSCTL 3 .Os .Sh NAME @@ -458,6 +458,7 @@ information. .It Dv KERN_POSIX1 Ta "integer" Ta "no" .It Dv KERN_PROC Ta "struct kinfo_proc" Ta "no" .It Dv KERN_PROC_ARGS Ta "node" Ta "not applicable" +.It Dv KERN_PROC_CWD Ta "string" Ta "not applicable" .It Dv KERN_PROF Ta "node" Ta "not applicable" .It Dv KERN_RAWPARTITION Ta "integer" Ta "no" .It Dv KERN_RND Ta "struct rndstats" Ta "no" @@ -762,6 +763,10 @@ followed by the strings themselves. The last char pointer is a .Dv NULL pointer. +.It Dv KERN_PROC_CWD +Return the current working directory of a process. +The third level name is the target process ID. +A NUL-terminated string is returned. .It Dv KERN_PROF Return profiling information about the kernel. If the kernel is not compiled for profiling, diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 780a79da71c..4e964d0008c 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.208 2011/09/18 13:23:38 miod Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.209 2011/12/09 16:14:54 nicm Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -117,6 +117,7 @@ extern void nmbclust_update(void); int sysctl_diskinit(int, struct proc *); int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *); +int sysctl_proc_cwd(int *, u_int, void *, size_t *, struct proc *); int sysctl_intrcnt(int *, u_int, void *, size_t *); int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t); int sysctl_emul(int *, u_int, void *, size_t *, void *, size_t); @@ -282,6 +283,7 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, case KERN_TTY: case KERN_POOL: case KERN_PROC_ARGS: + case KERN_PROC_CWD: case KERN_SYSVIPC_INFO: case KERN_SEMINFO: case KERN_SHMINFO: @@ -367,6 +369,9 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, case KERN_PROC_ARGS: return (sysctl_proc_args(name + 1, namelen - 1, oldp, oldlenp, p)); + case KERN_PROC_CWD: + return (sysctl_proc_cwd(name + 1, namelen - 1, oldp, oldlenp, + p)); case KERN_FILE2: return (sysctl_file2(name + 1, namelen - 1, oldp, oldlenp, p)); #endif @@ -1719,6 +1724,67 @@ out: return (error); } +int +sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp, + struct proc *cp) +{ + struct proc *findp; + pid_t pid; + int error; + size_t lenused, len; + char *path, *bp, *bend; + + if (namelen > 1) + return (ENOTDIR); + if (namelen < 1) + return (EINVAL); + + pid = name[0]; + if ((findp = pfind(pid)) == NULL) + return (ESRCH); + + if (oldp == NULL) { + *oldlenp = MAXPATHLEN * 4; + return (0); + } + + if (P_ZOMBIE(findp) || (findp->p_flag & P_SYSTEM)) + return (EINVAL); + + /* Only owner or root can get cwd */ + if (findp->p_ucred->cr_uid != cp->p_ucred->cr_uid && + (error = suser(cp, 0)) != 0) + return (error); + + /* Exiting - don't bother, it will be gone soon anyway */ + if (findp->p_flag & P_WEXIT) + return (ESRCH); + + len = *oldlenp; + if (len > MAXPATHLEN * 4) + len = MAXPATHLEN * 4; + else if (len < 2) + return (ERANGE); + *oldlenp = 0; + + path = malloc(len, M_TEMP, M_WAITOK); + + bp = &path[len]; + bend = bp; + *(--bp) = '\0'; + + /* Same as sys__getcwd */ + error = vfs_getcwd_common(findp->p_fd->fd_cdir, NULL, + &bp, path, len / 2, GETCWD_CHECK_ACCESS, cp); + if (error == 0) { + *oldlenp = lenused = bend - bp; + error = copyout(bp, oldp, lenused); + } + + free(path, M_TEMP); + + return (error); +} #endif /* diff --git a/sys/kern/vfs_getcwd.c b/sys/kern/vfs_getcwd.c index 4639dea989e..416a52044a5 100644 --- a/sys/kern/vfs_getcwd.c +++ b/sys/kern/vfs_getcwd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_getcwd.c,v 1.17 2010/05/19 08:31:23 thib Exp $ */ +/* $OpenBSD: vfs_getcwd.c,v 1.18 2011/12/09 16:14:54 nicm Exp $ */ /* $NetBSD: vfs_getcwd.c,v 1.3.2.3 1999/07/11 10:24:09 sommerfeld Exp $ */ /* @@ -260,8 +260,6 @@ vfs_getcwd_getcache(struct vnode **lvpp, struct vnode **uvpp, char **bpp, return (error); } -#define GETCWD_CHECK_ACCESS 0x0001 - /* Common routine shared by sys___getcwd() and vn_isunder() */ int vfs_getcwd_common(struct vnode *lvp, struct vnode *rvp, char **bpp, char *bufp, diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 4661df7a5c8..b7d220f605b 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.117 2011/08/30 01:09:29 guenther Exp $ */ +/* $OpenBSD: sysctl.h,v 1.118 2011/12/09 16:14:54 nicm Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -189,7 +189,8 @@ struct ctlname { #define KERN_CONSDEV 75 /* dev_t: console terminal device */ #define KERN_NETLIVELOCKS 76 /* int: number of network livelocks */ #define KERN_POOL_DEBUG 77 /* int: enable pool_debug */ -#define KERN_MAXID 78 /* number of valid kern ids */ +#define KERN_PROC_CWD 78 /* node: proc cwd */ +#define KERN_MAXID 79 /* number of valid kern ids */ #define CTL_KERN_NAMES { \ { 0, 0 }, \ @@ -270,6 +271,7 @@ struct ctlname { { "consdev", CTLTYPE_STRUCT }, \ { "netlivelocks", CTLTYPE_INT }, \ { "pool_debug", CTLTYPE_INT }, \ + { "proc_cwd", CTLTYPE_NODE }, \ } /* diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 02572eca367..ff5c091428a 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vnode.h,v 1.109 2011/04/05 14:34:16 thib Exp $ */ +/* $OpenBSD: vnode.h,v 1.110 2011/12/09 16:14:54 nicm Exp $ */ /* $NetBSD: vnode.h,v 1.38 1996/02/29 20:59:05 cgd Exp $ */ /* @@ -623,6 +623,7 @@ void vprint(char *, struct vnode *); void copy_statfs_info(struct statfs *, const struct mount *); /* vfs_getcwd.c */ +#define GETCWD_CHECK_ACCESS 0x0001 int vfs_getcwd_scandir(struct vnode **, struct vnode **, char **, char *, struct proc *); int vfs_getcwd_common(struct vnode *, struct vnode *, char **, char *, int, |