Module Name: src Committed By: christos Date: Sun Nov 7 13:47:50 UTC 2021
Modified Files: src/sys/kern: kern_exec.c vfs_syscalls.c src/sys/sys: spawn.h vfs_syscalls.h Log Message: Merge the kernel portion of the posix-spawn-chdir project by Piyush Sachdeva. To generate a diff of this commit: cvs rdiff -u -r1.510 -r1.511 src/sys/kern/kern_exec.c cvs rdiff -u -r1.553 -r1.554 src/sys/kern/vfs_syscalls.c cvs rdiff -u -r1.6 -r1.7 src/sys/sys/spawn.h cvs rdiff -u -r1.28 -r1.29 src/sys/sys/vfs_syscalls.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_exec.c diff -u src/sys/kern/kern_exec.c:1.510 src/sys/kern/kern_exec.c:1.511 --- src/sys/kern/kern_exec.c:1.510 Sun Oct 10 14:07:51 2021 +++ src/sys/kern/kern_exec.c Sun Nov 7 08:47:49 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.510 2021/10/10 18:07:51 thorpej Exp $ */ +/* $NetBSD: kern_exec.c,v 1.511 2021/11/07 13:47:49 christos Exp $ */ /*- * Copyright (c) 2008, 2019, 2020 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.510 2021/10/10 18:07:51 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.511 2021/11/07 13:47:49 christos Exp $"); #include "opt_exec.h" #include "opt_execfmt.h" @@ -103,6 +103,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_exec.c, #include <sys/module.h> #include <sys/syscallvar.h> #include <sys/syscallargs.h> +#include <sys/vfs_syscalls.h> #if NVERIEXEC > 0 #include <sys/verified_exec.h> #endif /* NVERIEXEC > 0 */ @@ -2132,6 +2133,13 @@ handle_posix_spawn_file_actions(struct p } error = fd_close(fae->fae_fildes); break; + case FAE_CHDIR: + error = do_sys_chdir(l, fae->fae_chdir_path, + UIO_SYSSPACE, &retval); + break; + case FAE_FCHDIR: + error = do_sys_fchdir(l, fae->fae_fildes, &retval); + break; } if (error) return error; @@ -2361,15 +2369,27 @@ spawn_return(void *arg) exit1(l, 127, 0); } +static __inline char ** +posix_spawn_fae_path(struct posix_spawn_file_actions_entry *fae) +{ + switch (fae->fae_action) { + case FAE_OPEN: + return &fae->fae_path; + case FAE_CHDIR: + return &fae->fae_chdir_path; + default: + return NULL; + } +} + void posix_spawn_fa_free(struct posix_spawn_file_actions *fa, size_t len) { for (size_t i = 0; i < len; i++) { - struct posix_spawn_file_actions_entry *fae = &fa->fae[i]; - if (fae->fae_action != FAE_OPEN) - continue; - kmem_strfree(fae->fae_path); + char **pathp = posix_spawn_fae_path(&fa->fae[i]); + if (pathp) + kmem_strfree(*pathp); } if (fa->len > 0) kmem_free(fa->fae, sizeof(*fa->fae) * fa->len); @@ -2408,14 +2428,14 @@ posix_spawn_fa_alloc(struct posix_spawn_ pbuf = PNBUF_GET(); for (; i < fa->len; i++) { - fae = &fa->fae[i]; - if (fae->fae_action != FAE_OPEN) + char **pathp = posix_spawn_fae_path(&fa->fae[i]); + if (pathp == NULL) continue; - error = copyinstr(fae->fae_path, pbuf, MAXPATHLEN, &fal); + error = copyinstr(*pathp, pbuf, MAXPATHLEN, &fal); if (error) goto out; - fae->fae_path = kmem_alloc(fal, KM_SLEEP); - memcpy(fae->fae_path, pbuf, fal); + *pathp = kmem_alloc(fal, KM_SLEEP); + memcpy(*pathp, pbuf, fal); } PNBUF_PUT(pbuf); Index: src/sys/kern/vfs_syscalls.c diff -u src/sys/kern/vfs_syscalls.c:1.553 src/sys/kern/vfs_syscalls.c:1.554 --- src/sys/kern/vfs_syscalls.c:1.553 Sun Sep 26 17:29:38 2021 +++ src/sys/kern/vfs_syscalls.c Sun Nov 7 08:47:50 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls.c,v 1.553 2021/09/26 21:29:38 thorpej Exp $ */ +/* $NetBSD: vfs_syscalls.c,v 1.554 2021/11/07 13:47:50 christos Exp $ */ /*- * Copyright (c) 2008, 2009, 2019, 2020 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.553 2021/09/26 21:29:38 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.554 2021/11/07 13:47:50 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_fileassoc.h" @@ -1459,24 +1459,19 @@ sys___getvfsstat90(struct lwp *l, const /* * Change current working directory to a given file descriptor. */ -/* ARGSUSED */ int -sys_fchdir(struct lwp *l, const struct sys_fchdir_args *uap, register_t *retval) +do_sys_fchdir(struct lwp *l, int fd, register_t *retval) { - /* { - syscallarg(int) fd; - } */ struct proc *p = l->l_proc; struct cwdinfo *cwdi; struct vnode *vp, *tdp; struct mount *mp; file_t *fp; - int error, fd; + int error; /* fd_getvnode() will use the descriptor for us */ - fd = SCARG(uap, fd); if ((error = fd_getvnode(fd, &fp)) != 0) - return (error); + return error; vp = fp->f_vnode; vref(vp); @@ -1517,9 +1512,22 @@ sys_fchdir(struct lwp *l, const struct s } rw_exit(&cwdi->cwdi_lock); - out: +out: fd_putfile(fd); - return (error); + return error; +} + +/* + * Change current working directory to a given file descriptor. + */ +/* ARGSUSED */ +int +sys_fchdir(struct lwp *l, const struct sys_fchdir_args *uap, register_t *retval) +{ + /* { + syscallarg(int) fd; + } */ + return do_sys_fchdir(l, SCARG(uap, fd), retval); } /* @@ -1559,27 +1567,36 @@ sys_fchroot(struct lwp *l, const struct /* * Change current working directory (``.''). */ -/* ARGSUSED */ int -sys_chdir(struct lwp *l, const struct sys_chdir_args *uap, register_t *retval) +do_sys_chdir(struct lwp *l, const char *path, enum uio_seg seg, + register_t *retval) { - /* { - syscallarg(const char *) path; - } */ struct proc *p = l->l_proc; - struct cwdinfo *cwdi; + struct cwdinfo * cwdi; int error; struct vnode *vp; - if ((error = chdir_lookup(SCARG(uap, path), UIO_USERSPACE, - &vp, l)) != 0) - return (error); + if ((error = chdir_lookup(path, seg, &vp, l)) != 0) + return error; cwdi = p->p_cwdi; rw_enter(&cwdi->cwdi_lock, RW_WRITER); vrele(cwdi->cwdi_cdir); cwdi->cwdi_cdir = vp; rw_exit(&cwdi->cwdi_lock); - return (0); + return 0; +} + +/* + * Change current working directory (``.''). + */ +/* ARGSUSED */ +int +sys_chdir(struct lwp *l, const struct sys_chdir_args *uap, register_t *retval) +{ + /* { + syscallarg(const char *) path; + } */ + return do_sys_chdir(l, SCARG(uap, path), UIO_USERSPACE, retval); } /* Index: src/sys/sys/spawn.h diff -u src/sys/sys/spawn.h:1.6 src/sys/sys/spawn.h:1.7 --- src/sys/sys/spawn.h:1.6 Wed Nov 29 15:15:21 2017 +++ src/sys/sys/spawn.h Sun Nov 7 08:47:49 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: spawn.h,v 1.6 2017/11/29 20:15:21 snj Exp $ */ +/* $NetBSD: spawn.h,v 1.7 2021/11/07 13:47:49 christos Exp $ */ /*- * Copyright (c) 2008 Ed Schouten <e...@freebsd.org> @@ -47,7 +47,7 @@ struct posix_spawnattr { sigset_t sa_sigmask; }; -enum fae_action { FAE_OPEN, FAE_DUP2, FAE_CLOSE }; +enum fae_action { FAE_OPEN, FAE_DUP2, FAE_CLOSE, FAE_CHDIR, FAE_FCHDIR }; typedef struct posix_spawn_file_actions_entry { enum fae_action fae_action; @@ -65,6 +65,10 @@ typedef struct posix_spawn_file_actions_ int newfildes; #define fae_newfildes fae_data.dup2.newfildes } dup2; + struct { + char *path; +#define fae_chdir_path fae_data.chdir.path + } chdir; } fae_data; } posix_spawn_file_actions_entry_t; Index: src/sys/sys/vfs_syscalls.h diff -u src/sys/sys/vfs_syscalls.h:1.28 src/sys/sys/vfs_syscalls.h:1.29 --- src/sys/sys/vfs_syscalls.h:1.28 Mon Apr 20 17:39:05 2020 +++ src/sys/sys/vfs_syscalls.h Sun Nov 7 08:47:49 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls.h,v 1.28 2020/04/20 21:39:05 ad Exp $ */ +/* $NetBSD: vfs_syscalls.h,v 1.29 2021/11/07 13:47:49 christos Exp $ */ /* * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -80,6 +80,8 @@ int do_sys_mkdir(const char *, mode_t, e int do_sys_symlink(const char *, const char *, enum uio_seg); int do_sys_quotactl(const char *, const struct quotactl_args *); void do_sys_sync(struct lwp *); +int do_sys_chdir(struct lwp *, const char *, enum uio_seg, register_t *); +int do_sys_fchdir(struct lwp *, int, register_t *); int vfs_syncwait(void); int chdir_lookup(const char *, int, struct vnode **, struct lwp *);