exec: Introduce the PROC_PS_STRINGS() macro

Rather than fetching the ps_strings address directly from a process'
sysentvec, use this macro.  With stack address randomization the
ps_strings address is no longer fixed.

Reviewed by:	kib
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D33704
This commit is contained in:
Mark Johnston 2022-01-17 11:42:28 -05:00
parent 5a8413e779
commit 706f4a81a8
14 changed files with 51 additions and 35 deletions

View File

@ -422,7 +422,7 @@ ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
}
regs->tf_rsp = (uintptr_t)fp;
regs->tf_rip = p->p_sysent->sv_psstrings -
regs->tf_rip = PROC_PS_STRINGS(p) -
(_binary_elf_vdso32_so_1_end - _binary_elf_vdso32_so_1_start) +
VDSO_IA32_OSIGCODE_OFFSET;
regs->tf_rflags &= ~(PSL_T | PSL_D);

View File

@ -270,7 +270,7 @@ setup_lcall_gate(void)
bzero(&uap, sizeof(uap));
uap.start = 0;
uap.num = 1;
lcall_addr = curproc->p_sysent->sv_psstrings -
lcall_addr = PROC_PS_STRINGS(curproc) -
(_binary_elf_vdso32_so_1_end - _binary_elf_vdso32_so_1_start) +
VDSO_LCALL_TRAMP_OFFSET;
bzero(&desc, sizeof(desc));

View File

@ -359,7 +359,7 @@ linux_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
struct proc *p;
p = imgp->proc;
arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
arginfo = (struct ps_strings *)PROC_PS_STRINGS(p);
destp = (uintptr_t)arginfo;
if (imgp->execpath != NULL && imgp->auxargs != NULL) {

View File

@ -43,6 +43,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
@ -63,6 +64,11 @@ __FBSDID("$FreeBSD$");
#include <machine/vfp.h>
#include <machine/vmparam.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
/*
* Clear registers on exec
*/
@ -340,7 +346,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
if (sysent->sv_sigcode_base != 0)
tf->tf_usr_lr = (register_t)sysent->sv_sigcode_base;
else
tf->tf_usr_lr = (register_t)(sysent->sv_psstrings -
tf->tf_usr_lr = (register_t)(PROC_PS_STRINGS(p) -
*(sysent->sv_szsigcode));
/* Set the mode to enter in the signal handler */
#if __ARM_ARCH >= 7

View File

@ -27,7 +27,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/exec.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
@ -42,6 +43,11 @@ __FBSDID("$FreeBSD$");
#include <compat/freebsd32/freebsd32_proto.h>
#include <compat/freebsd32/freebsd32_signal.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
extern void freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
/*
@ -390,7 +396,7 @@ freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
if (sysent->sv_sigcode_base != 0)
tf->tf_x[14] = (register_t)sysent->sv_sigcode_base;
else
tf->tf_x[14] = (register_t)(sysent->sv_psstrings -
tf->tf_x[14] = (register_t)(PROC_PS_STRINGS(p) -
*(sysent->sv_szsigcode));
/* Set the mode to enter in the signal handler */
if ((register_t)catcher & 1)

View File

@ -256,7 +256,7 @@ linux_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
int argc, envc, error;
p = imgp->proc;
arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
arginfo = (struct ps_strings *)PROC_PS_STRINGS(p);
destp = (uintptr_t)arginfo;
if (imgp->execpath != NULL && imgp->auxargs != NULL) {

View File

@ -3404,7 +3404,7 @@ freebsd32_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
sysent = imgp->sysent;
arginfo = (struct freebsd32_ps_strings *)sysent->sv_psstrings;
arginfo = (struct freebsd32_ps_strings *)PROC_PS_STRINGS(imgp->proc);
imgp->ps_strings = arginfo;
destp = (uintptr_t)arginfo;

View File

@ -238,7 +238,7 @@ osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
szosigcode;
} else {
/* a.out sysentvec does not use shared page */
regs->tf_eip = p->p_sysent->sv_psstrings - szosigcode;
regs->tf_eip = PROC_PS_STRINGS(p) - szosigcode;
}
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
@ -523,7 +523,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_esp = (int)sfp;
regs->tf_eip = p->p_sysent->sv_sigcode_base;
if (regs->tf_eip == 0)
regs->tf_eip = p->p_sysent->sv_psstrings - szsigcode;
regs->tf_eip = PROC_PS_STRINGS(p) - szsigcode;
regs->tf_eflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;

View File

@ -212,7 +212,7 @@ linux_copyout_auxargs(struct image_params *imgp, uintptr_t base)
p = imgp->proc;
issetugid = imgp->proc->p_flag & P_SUGID ? 1 : 0;
arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
arginfo = (struct ps_strings *)PROC_PS_STRINGS(p);
args = (Elf32_Auxargs *)imgp->auxargs;
argarray = pos = malloc(LINUX_AT_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
@ -290,7 +290,7 @@ linux_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
struct proc *p;
p = imgp->proc;
arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
arginfo = (struct ps_strings *)PROC_PS_STRINGS(p);
destp = (uintptr_t)arginfo;
if (imgp->execpath != NULL && imgp->auxargs != NULL) {

View File

@ -2516,9 +2516,9 @@ __elfN(note_procstat_psstrings)(void *arg, struct sbuf *sb, size_t *sizep)
KASSERT(*sizep == size, ("invalid size"));
structsize = sizeof(ps_strings);
#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32
ps_strings = PTROUT(p->p_sysent->sv_psstrings);
ps_strings = PTROUT(PROC_PS_STRINGS(p));
#else
ps_strings = p->p_sysent->sv_psstrings;
ps_strings = PROC_PS_STRINGS(p);
#endif
sbuf_bcat(sb, &structsize, sizeof(structsize));
sbuf_bcat(sb, &ps_strings, sizeof(ps_strings));

View File

@ -160,19 +160,18 @@ static int
sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS)
{
struct proc *p;
int error;
vm_offset_t ps_strings;
p = curproc;
#ifdef SCTL_MASK32
if (req->flags & SCTL_MASK32) {
unsigned int val;
val = (unsigned int)p->p_sysent->sv_psstrings;
error = SYSCTL_OUT(req, &val, sizeof(val));
} else
val = (unsigned int)PROC_PS_STRINGS(p);
return (SYSCTL_OUT(req, &val, sizeof(val)));
}
#endif
error = SYSCTL_OUT(req, &p->p_sysent->sv_psstrings,
sizeof(p->p_sysent->sv_psstrings));
return error;
ps_strings = PROC_PS_STRINGS(p);
return (SYSCTL_OUT(req, &ps_strings, sizeof(ps_strings)));
}
static int
@ -1595,9 +1594,8 @@ exec_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
p = imgp->proc;
sysent = p->p_sysent;
arginfo = (struct ps_strings *)sysent->sv_psstrings;
destp = (uintptr_t)arginfo;
imgp->ps_strings = arginfo;
destp = PROC_PS_STRINGS(p);
arginfo = imgp->ps_strings = (void *)destp;
/*
* Install sigcode.

View File

@ -1838,8 +1838,8 @@ get_proc_vector32(struct thread *td, struct proc *p, char ***proc_vectorp,
int i, error;
error = 0;
if (proc_readmem(td, p, (vm_offset_t)p->p_sysent->sv_psstrings, &pss,
sizeof(pss)) != sizeof(pss))
if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) !=
sizeof(pss))
return (ENOMEM);
switch (type) {
case PROC_ARG:
@ -1914,8 +1914,8 @@ get_proc_vector(struct thread *td, struct proc *p, char ***proc_vectorp,
if (SV_PROC_FLAG(p, SV_ILP32) != 0)
return (get_proc_vector32(td, p, proc_vectorp, vsizep, type));
#endif
if (proc_readmem(td, p, (vm_offset_t)p->p_sysent->sv_psstrings, &pss,
sizeof(pss)) != sizeof(pss))
if (proc_readmem(td, p, PROC_PS_STRINGS(p), &pss, sizeof(pss)) !=
sizeof(pss))
return (ENOMEM);
switch (type) {
case PROC_ARG:
@ -2980,13 +2980,13 @@ sysctl_kern_proc_ps_strings(SYSCTL_HANDLER_ARGS)
* process.
*/
ps_strings32 = SV_PROC_FLAG(p, SV_ILP32) != 0 ?
PTROUT(p->p_sysent->sv_psstrings) : 0;
PTROUT(PROC_PS_STRINGS(p)) : 0;
PROC_UNLOCK(p);
error = SYSCTL_OUT(req, &ps_strings32, sizeof(ps_strings32));
return (error);
}
#endif
ps_strings = p->p_sysent->sv_psstrings;
ps_strings = PROC_PS_STRINGS(p);
PROC_UNLOCK(p);
error = SYSCTL_OUT(req, &ps_strings, sizeof(ps_strings));
return (error);
@ -3103,9 +3103,9 @@ sysctl_kern_proc_sigtramp(SYSCTL_HANDLER_ARGS)
*sv->sv_szsigcode :
(uintptr_t)sv->sv_szsigcode);
} else {
kst32.ksigtramp_start = sv->sv_psstrings -
kst32.ksigtramp_start = PROC_PS_STRINGS(p) -
*sv->sv_szsigcode;
kst32.ksigtramp_end = sv->sv_psstrings;
kst32.ksigtramp_end = PROC_PS_STRINGS(p);
}
}
PROC_UNLOCK(p);
@ -3120,9 +3120,9 @@ sysctl_kern_proc_sigtramp(SYSCTL_HANDLER_ARGS)
((sv->sv_flags & SV_DSO_SIG) == 0 ? *sv->sv_szsigcode :
(uintptr_t)sv->sv_szsigcode);
} else {
kst.ksigtramp_start = (char *)sv->sv_psstrings -
kst.ksigtramp_start = (char *)PROC_PS_STRINGS(p) -
*sv->sv_szsigcode;
kst.ksigtramp_end = (char *)sv->sv_psstrings;
kst.ksigtramp_end = (char *)PROC_PS_STRINGS(p);
}
PROC_UNLOCK(p);
error = SYSCTL_OUT(req, &kst, sizeof(kst));

View File

@ -65,6 +65,11 @@ __FBSDID("$FreeBSD$");
#include <machine/sbi.h>
#include <machine/trap.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#ifdef FPE
#include <machine/fpe.h>
#endif
@ -409,7 +414,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
if (sysent->sv_sigcode_base != 0)
tf->tf_ra = (register_t)sysent->sv_sigcode_base;
else
tf->tf_ra = (register_t)(sysent->sv_psstrings -
tf->tf_ra = (register_t)(PROC_PS_STRINGS(p) -
*(sysent->sv_szsigcode));
CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_sepc,

View File

@ -87,6 +87,7 @@ struct execsw {
* Prefer the kern.ps_strings or kern.proc.ps_strings sysctls to this constant.
*/
#define PS_STRINGS (USRSTACK - sizeof(struct ps_strings))
#define PROC_PS_STRINGS(p) ((p)->p_sysent->sv_psstrings)
int exec_map_first_page(struct image_params *);
void exec_unmap_first_page(struct image_params *);