# HG changeset patch # User Taylor R Campbell # Date 1740606281 0 # Wed Feb 26 21:44:41 2025 +0000 # Branch trunk # Node ID 206d8d62e8de546e2096c34034c8ed95a5b2f06b # Parent 52b6ac2ed16adf4d62c8c33fef2a1dca9fe160c0 # EXP-Topic riastradh-pr59085-execregleak Clear trapframe on exec. Do this for all architectures, even if the trapframe is fully initialized -- makes it easier to audit and be confident it's correct, and most likely (with the exception of sh3 which has an intermediate call to ufetch_int in the middle) the compiler can eliminate redundant stores in these routines. PR kern/59084: exec/spawn leaks register content diff -r 52b6ac2ed16a -r 206d8d62e8de sys/arch/alpha/alpha/machdep.c --- a/sys/arch/alpha/alpha/machdep.c Fri Feb 28 15:12:20 2025 +0000 +++ b/sys/arch/alpha/alpha/machdep.c Wed Feb 26 21:44:41 2025 +0000 @@ -1684,11 +1684,11 @@ setregs(register struct lwp *l, struct e panic("crash requested by boot flags"); #endif + memset(tfp, 0, sizeof(*tfp)); + #ifdef DEBUG for (i = 0; i < FRAME_SIZE; i++) tfp->tf_regs[i] = 0xbabefacedeadbeef; -#else - memset(tfp->tf_regs, 0, FRAME_SIZE * sizeof tfp->tf_regs[0]); #endif pcb = lwp_getpcb(l); memset(&pcb->pcb_fp, 0, sizeof(pcb->pcb_fp)); diff -r 52b6ac2ed16a -r 206d8d62e8de sys/arch/amd64/amd64/machdep.c --- a/sys/arch/amd64/amd64/machdep.c Fri Feb 28 15:12:20 2025 +0000 +++ b/sys/arch/amd64/amd64/machdep.c Wed Feb 26 21:44:41 2025 +0000 @@ -1388,6 +1388,8 @@ setregs(struct lwp *l, struct exec_packa kpreempt_enable(); tf = l->l_md.md_regs; + memset(tf, 0, sizeof(*tf)); + tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL); tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL); tf->tf_rdi = 0; diff -r 52b6ac2ed16a -r 206d8d62e8de sys/arch/hppa/hppa/machdep.c --- a/sys/arch/hppa/hppa/machdep.c Fri Feb 28 15:12:20 2025 +0000 +++ b/sys/arch/hppa/hppa/machdep.c Wed Feb 26 21:44:41 2025 +0000 @@ -1889,6 +1889,22 @@ setregs(struct lwp *l, struct exec_packa struct trapframe *tf = l->l_md.md_regs; struct pcb *pcb = lwp_getpcb(l); + memset(tf, 0, sizeof(*tf)); + + /* + * Initialize the External Interrupt Enable Mask, Processor + * Status Word, and NetBSD's floating-point register area + * pointer to the correct defaults for a user process. + * + * XXXMPSAFE If curcpu()->ci_eiem can vary from CPU to CPU, we + * have bigger problems here -- if the lwp is migrated from one + * CPU to another CPU between when the trapframe is saved and + * when the trapframe is restored, it might be invalidated. + */ + tf->tf_eiem = curcpu()->ci_eiem; + tf->tf_ipsw = PSW_MBS; + tf->tf_cr30 = (u_int)pcb->pcb_fpregs; + tf->tf_flags = TFF_SYS|TFF_LAST; tf->tf_iioq_tail = 4 + (tf->tf_iioq_head = pack->ep_entry | HPPA_PC_PRIV_USER); @@ -1906,6 +1922,7 @@ setregs(struct lwp *l, struct exec_packa /* reset any of the pending FPU exceptions */ hppa_fpu_flush(l); + memset(pcb->pcb_fpregs, 0, sizeof(*pcb->pcb_fpregs)); pcb->pcb_fpregs->fpr_regs[0] = ((uint64_t)HPPA_FPU_INIT) << 32; pcb->pcb_fpregs->fpr_regs[1] = 0; pcb->pcb_fpregs->fpr_regs[2] = 0; diff -r 52b6ac2ed16a -r 206d8d62e8de sys/arch/i386/i386/machdep.c --- a/sys/arch/i386/i386/machdep.c Fri Feb 28 15:12:20 2025 +0000 +++ b/sys/arch/i386/i386/machdep.c Wed Feb 26 21:44:41 2025 +0000 @@ -859,6 +859,8 @@ setregs(struct lwp *l, struct exec_packa x86_dbregs_clear(l); tf = l->l_md.md_regs; + memset(tf, 0, sizeof(*tf)); + tf->tf_gs = GSEL(GUGS_SEL, SEL_UPL); tf->tf_fs = GSEL(GUFS_SEL, SEL_UPL); tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL); diff -r 52b6ac2ed16a -r 206d8d62e8de sys/arch/ia64/ia64/machdep.c --- a/sys/arch/ia64/ia64/machdep.c Fri Feb 28 15:12:20 2025 +0000 +++ b/sys/arch/ia64/ia64/machdep.c Wed Feb 26 21:44:41 2025 +0000 @@ -710,6 +710,8 @@ setregs(register struct lwp *l, struct e vaddr_t uv = uvm_lwp_getuarea(l); tf = l->l_md.md_tf; + memset(tf, 0, sizeof(*tf)); + regstkp = uv + sizeof(struct pcb); ksttop = diff -r 52b6ac2ed16a -r 206d8d62e8de sys/arch/m68k/m68k/m68k_machdep.c --- a/sys/arch/m68k/m68k/m68k_machdep.c Fri Feb 28 15:12:20 2025 +0000 +++ b/sys/arch/m68k/m68k/m68k_machdep.c Wed Feb 26 21:44:41 2025 +0000 @@ -93,6 +93,8 @@ setregs(struct lwp *l, struct exec_packa struct trapframe *tf = (struct trapframe *)l->l_md.md_regs; struct pcb *pcb = lwp_getpcb(l); + memset(tf, 0, sizeof(*tf)); + tf->tf_sr = PSL_USERSET; tf->tf_pc = pack->ep_entry & ~1; tf->tf_regs[D0] = 0; diff -r 52b6ac2ed16a -r 206d8d62e8de sys/arch/mips/mips/mips_machdep.c --- a/sys/arch/mips/mips/mips_machdep.c Fri Feb 28 15:12:20 2025 +0000 +++ b/sys/arch/mips/mips/mips_machdep.c Wed Feb 26 21:44:41 2025 +0000 @@ -1697,7 +1697,7 @@ setregs(struct lwp *l, struct exec_packa struct trapframe * const tf = l->l_md.md_utf; struct proc * const p = l->l_proc; - memset(tf, 0, sizeof(struct trapframe)); + memset(tf, 0, sizeof(*tf)); tf->tf_regs[_R_SP] = (intptr_t)stack; tf->tf_regs[_R_PC] = (intptr_t)pack->ep_entry & ~3; tf->tf_regs[_R_T9] = (intptr_t)pack->ep_entry & ~3; /* abicall requirement */ diff -r 52b6ac2ed16a -r 206d8d62e8de sys/arch/sh3/sh3/sh3_machdep.c --- a/sys/arch/sh3/sh3/sh3_machdep.c Fri Feb 28 15:12:20 2025 +0000 +++ b/sys/arch/sh3/sh3/sh3_machdep.c Wed Feb 26 21:44:41 2025 +0000 @@ -518,6 +518,7 @@ setregs(struct lwp *l, struct exec_packa l->l_md.md_flags &= ~(MDL_USEDFPU | MDL_SSTEP); tf = l->l_md.md_regs; + memset(tf, 0, sizeof(*tf)); tf->tf_ssr = PSL_USERSET; tf->tf_spc = pack->ep_entry; diff -r 52b6ac2ed16a -r 206d8d62e8de sys/arch/vax/vax/trap.c --- a/sys/arch/vax/vax/trap.c Fri Feb 28 15:12:20 2025 +0000 +++ b/sys/arch/vax/vax/trap.c Wed Feb 26 21:44:41 2025 +0000 @@ -371,6 +371,8 @@ setregs(struct lwp *l, struct exec_packa { struct trapframe * const tf = l->l_md.md_utf; + memset(tf, 0, sizeof(*tf)); + tf->tf_pc = pack->ep_entry + 2; tf->tf_sp = stack; tf->tf_r6 = stack; /* for ELF */ diff -r 52b6ac2ed16a -r 206d8d62e8de tests/kernel/t_execregs.c --- a/tests/kernel/t_execregs.c Fri Feb 28 15:12:20 2025 +0000 +++ b/tests/kernel/t_execregs.c Wed Feb 26 21:44:41 2025 +0000 @@ -80,13 +80,6 @@ checkregs(const register_t regs[static N } #endif -#if defined(__hppa__) || \ - defined(__ia64__) || \ - defined(__vax__) || \ - defined(__x86_64__) - atf_tc_expect_fail("PR kern/59084: exec/spawn leaks register content"); -#endif - for (i = 0; i < NEXECREGS; i++) { if (regs[i] != 0) { for (i = 0; i < NEXECREGS; i++) {