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:
parent
5a8413e779
commit
706f4a81a8
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user