From cf3cc6322c4f1d694e223a2efa6f0c7d9f768c55 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 23 Aug 2023 13:42:25 -0700 Subject: [PATCH] Fix get_ps_strings for CHERI The argument and environment vectors are arrays of `char * __capability` not arrays of `char *`. This fixes kern.proc.args if the arguments are long enough to overflow the p_args cache which in turn fixes the bin/pkill/pgrep-f_test:main test which used an ARG_MAX command line. --- sys/kern/kern_proc.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 3225171d72fe..f311a28a819b 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1959,8 +1959,8 @@ pargs_drop(struct pargs *pa) } static int -proc_read_string(struct thread *td, struct proc *p, const char *sptr, char *buf, - size_t len) +proc_read_string(struct thread *td, struct proc *p, + const char * __capability sptr, char *buf, size_t len) { ssize_t n; @@ -1969,7 +1969,7 @@ proc_read_string(struct thread *td, struct proc *p, const char *sptr, char *buf, * and is aligned at the end of the page, and the following page is not * mapped. */ - n = proc_readmem(td, p, (vm_offset_t)sptr, buf, len); + n = proc_readmem(td, p, (__cheri_addr vm_offset_t)sptr, buf, len); if (n <= 0) return (ENOMEM); return (0); @@ -1985,14 +1985,15 @@ enum proc_vector_type { #ifdef COMPAT_FREEBSD32 static int -get_proc_vector32(struct thread *td, struct proc *p, char ***proc_vectorp, +get_proc_vector32(struct thread *td, struct proc *p, + char * __capability **proc_vectorp, size_t *vsizep, enum proc_vector_type type) { struct freebsd32_ps_strings pss; Elf32_Auxinfo aux; vm_offset_t vptr, ptr; uint32_t *proc_vector32; - char **proc_vector; + char * __capability *proc_vector; size_t vsize, size; int i, error; @@ -2043,7 +2044,7 @@ get_proc_vector32(struct thread *td, struct proc *p, char ***proc_vectorp, goto done; } if (type == PROC_AUX) { - *proc_vectorp = (char **)proc_vector32; + *proc_vectorp = (char * __capability *)(uintptr_t)proc_vector32; *vsizep = vsize; return (0); } @@ -2060,7 +2061,8 @@ get_proc_vector32(struct thread *td, struct proc *p, char ***proc_vectorp, #ifdef COMPAT_FREEBSD64 static int -get_proc_vector64(struct thread *td, struct proc *p, char ***proc_vectorp, +get_proc_vector64(struct thread *td, struct proc *p, + char * __capability **proc_vectorp, size_t *vsizep, enum proc_vector_type type) { struct freebsd64_ps_strings pss; @@ -2118,7 +2120,7 @@ get_proc_vector64(struct thread *td, struct proc *p, char ***proc_vectorp, goto done; } if (type == PROC_AUX) { - *proc_vectorp = (char **)proc_vector64; + *proc_vectorp = (char * __capability *)(uintptr_t)proc_vector64; *vsizep = vsize; return (0); } @@ -2126,7 +2128,7 @@ get_proc_vector64(struct thread *td, struct proc *p, char ***proc_vectorp, M_WAITOK); for (i = 0; i < (int)vsize; i++) proc_vector[i] = cheri_fromint(proc_vector64[i]); - *proc_vectorp = (char **)proc_vector; + *proc_vectorp = proc_vector; *vsizep = vsize; done: free(proc_vector64, M_TEMP); @@ -2135,13 +2137,14 @@ get_proc_vector64(struct thread *td, struct proc *p, char ***proc_vectorp, #endif static int -get_proc_vector(struct thread *td, struct proc *p, char ***proc_vectorp, +get_proc_vector(struct thread *td, struct proc *p, + char * __capability **proc_vectorp, size_t *vsizep, enum proc_vector_type type) { struct ps_strings pss; Elf_Auxinfo aux; vm_offset_t vptr, ptr; - char **proc_vector; + char * __capability *proc_vector; size_t vsize, size; int i; @@ -2233,7 +2236,7 @@ get_ps_strings(struct thread *td, struct proc *p, struct sbuf *sb, { size_t done, len, nchr, vsize; int error, i; - char **proc_vector, *sptr; + char * __capability *proc_vector, * __capability sptr; char pss_string[GET_PS_STRINGS_CHUNK_SZ]; PROC_ASSERT_HELD(p); @@ -2293,7 +2296,7 @@ int proc_getauxv(struct thread *td, struct proc *p, struct sbuf *sb) { size_t vsize, size; - char **auxv; + char * __capability *auxv; int error; error = get_proc_vector(td, p, &auxv, &vsize, PROC_AUX);