From 9df1c38bbc816bbac7b85701971478bf976c68c4 Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Wed, 15 Apr 2020 20:23:55 +0000 Subject: [PATCH] Export argc, argv, envc, envv, and ps_strings in auxargs. This simplifies discovery of these values, potentially with reducing the number of syscalls we need to make at runtime. Longer term, we wish to convert the startup process to pass an auxargs pointer to _start() and use that rather than walking off the end of envv. This is cleaner, more C-friendly, and for systems with strong bounds (e.g. CHERI) necessary. Reviewed by: kib Obtained from: CheriBSD Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D24407 --- sys/compat/freebsd32/freebsd32_misc.c | 2 ++ sys/kern/imgact_elf.c | 5 +++++ sys/kern/kern_exec.c | 2 ++ sys/sys/elf_common.h | 7 ++++++- sys/sys/imgact.h | 2 ++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 9480d437bd9a..89088a2aba42 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -3237,6 +3237,7 @@ freebsd32_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) /* * Fill in "ps_strings" struct for ps, w, etc. */ + imgp->argv = vectp; if (suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp) != 0 || suword32(&arginfo->ps_nargvstr, argc) != 0) return (EFAULT); @@ -3256,6 +3257,7 @@ freebsd32_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) if (suword32(vectp++, 0) != 0) return (EFAULT); + imgp->envv = vectp; if (suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp) != 0 || suword32(&arginfo->ps_nenvstr, envc) != 0) return (EFAULT); diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index bbd5fcd5249e..3ab22ed4f03b 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1374,6 +1374,11 @@ __elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t base) AUXARGS_ENTRY(pos, AT_HWCAP2, *imgp->sysent->sv_hwcap2); AUXARGS_ENTRY(pos, AT_BSDFLAGS, __elfN(sigfastblock) ? ELF_BSDF_SIGFASTBLK : 0); + AUXARGS_ENTRY(pos, AT_ARGC, imgp->args->argc); + AUXARGS_ENTRY_PTR(pos, AT_ARGV, imgp->argv); + AUXARGS_ENTRY(pos, AT_ENVC, imgp->args->envc); + AUXARGS_ENTRY_PTR(pos, AT_ENVV, imgp->envv); + AUXARGS_ENTRY_PTR(pos, AT_PS_STRINGS, imgp->ps_strings); AUXARGS_ENTRY(pos, AT_NULL, 0); free(imgp->auxargs, M_TEMP); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index c99bd884668d..197ca3bc9dcb 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1646,6 +1646,7 @@ exec_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) /* * Fill in "ps_strings" struct for ps, w, etc. */ + imgp->argv = vectp; if (suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp) != 0 || suword32(&arginfo->ps_nargvstr, argc) != 0) return (EFAULT); @@ -1665,6 +1666,7 @@ exec_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) if (suword(vectp++, 0) != 0) return (EFAULT); + imgp->envv = vectp; if (suword(&arginfo->ps_envstr, (long)(intptr_t)vectp) != 0 || suword32(&arginfo->ps_nenvstr, envc) != 0) return (EFAULT); diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h index 41bc89be6cf7..d6b0f71adbd9 100644 --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -956,8 +956,13 @@ typedef struct { #define AT_HWCAP 25 /* CPU feature flags. */ #define AT_HWCAP2 26 /* CPU feature flags 2. */ #define AT_BSDFLAGS 27 /* ELF BSD Flags. */ +#define AT_ARGC 28 /* Argument count */ +#define AT_ARGV 29 /* Argument vector */ +#define AT_ENVC 30 /* Environment count */ +#define AT_ENVV 31 /* Environment vector */ +#define AT_PS_STRINGS 32 /* struct ps_strings */ -#define AT_COUNT 28 /* Count of defined aux entry types. */ +#define AT_COUNT 33 /* Count of defined aux entry types. */ /* * Relocation types. diff --git a/sys/sys/imgact.h b/sys/sys/imgact.h index 35ddbbd946f3..b29200143189 100644 --- a/sys/sys/imgact.h +++ b/sys/sys/imgact.h @@ -78,6 +78,8 @@ struct image_params { void *ps_strings; /* pointer to ps_string (user space) */ struct image_args *args; /* system call arguments */ struct sysentvec *sysent; /* system entry vector */ + void *argv; /* pointer to argv (user space) */ + void *envv; /* pointer to envv (user space) */ char *execpath; unsigned long execpathp; char *freepath;