David Higgs recently reported an incorrect usage of uvm_map_protect(9): https://marc.info/?l=openbsd-tech&m=174001772620750&w=2
It turns out there's another one in exec_sigcode_map(), fixed by the diff below. Currently the uvm_map_protect(9) calls has no effect and returns EINVAL. However, on amd64, with the diff applied the kernel faults when writing to curproc. In the trace below tatclock+0x108 corresponds to tu_enter(&p->p_tu) in statclock(). panic(ffffffff81d89ec1) at panic+0xdd witness_checkorder(ffffffff820236d0,1,0) at witness_checkorder+0x8ae rw_do_enter_read(ffffffff820236b8,0) at rw_do_enter_read+0x4c uvmfault_lookup(ffff800003aa1810,0) at uvmfault_lookup+0x8a uvm_fault_check(ffff800003aa1810,ffff800003aa1848,ffff800003aa1878,0) at uvm_fa ult_check+0x38 uvm_fault(ffffffff820235d0,ffff8000fffff000,0,2) at uvm_fault+0xed kpageflttrap(ffff800003aa1990,ffff8000fffff8a8) at kpageflttrap+0x158 kerntrap(ffff800003aa1990) at kerntrap+0xaf alltraps_kern_meltdown() at alltraps_kern_meltdown+0x7b statclock(ffffffff81fd8dc8,ffff800003aa1bb0,0) at statclock+0x108 clockintr_dispatch(ffff800003aa1bb0) at clockintr_dispatch+0x249 clockintr(ffff800003aa1bb0) at clockintr+0x59 intr_handler(ffff800003aa1bb0,ffff80000008fe80) at intr_handler+0x91 Xintr_legacy0_untramp() at Xintr_legacy0_untramp+0x1a3 pmap_write_protect(ffffffff82022a20,ffff800003b14000,ffff800003b15000,1) at pma p_write_protect+0x13f uvm_map_protect(ffffffff820235d0,ffff800003b14000,ffff800003b15000,1,0,0,56f497 690e6c544a) at uvm_map_protect+0x47a exec_sigcode_map(ffff800003aa7288) at exec_sigcode_map+0x22e sys_execve(ffff8000fffff710,ffff800003aa2330,ffff800003aa23e0) at sys_execve+0x 11db start_init(ffff8000fffff710) at start_init+0x2e8 On arm64 the kernel works fine with this diff. Any idea of what is happening? Index: kern/exec_subr.c =================================================================== RCS file: /cvs/src/sys/kern/exec_subr.c,v diff -u -p -r1.68 exec_subr.c --- kern/exec_subr.c 2 Nov 2024 10:02:23 -0000 1.68 +++ kern/exec_subr.c 10 Mar 2025 19:26:50 -0000 @@ -260,7 +260,7 @@ vmcmd_map_readvn(struct proc *p, struct * uvm_map_protect() to fix up the protection. ICK. */ error = (uvm_map_protect(&p->p_vmspace->vm_map, - cmd->ev_addr, round_page(cmd->ev_len), + cmd->ev_addr, round_page(cmd->ev_addr + cmd->ev_len), prot, 0, FALSE, TRUE)); } if (error == 0) { Index: kern/kern_exec.c =================================================================== RCS file: /cvs/src/sys/kern/kern_exec.c,v diff -u -p -r1.262 kern_exec.c --- kern/kern_exec.c 17 Feb 2025 10:07:10 -0000 1.262 +++ kern/kern_exec.c 25 Mar 2025 13:56:34 -0000 @@ -874,12 +874,11 @@ exec_sigcode_map(struct process *pr) int r; sigobject = uao_create(sz, 0); - uao_reference(sigobject); /* permanent reference */ - if ((r = uvm_map(kernel_map, &va, round_page(sz), sigobject, 0, 0, UVM_MAPFLAG(PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE, MAP_INHERIT_SHARE, MADV_RANDOM, 0)))) { uao_detach(sigobject); + sigobject = NULL; return (ENOMEM); } @@ -890,9 +889,13 @@ exec_sigcode_map(struct process *pr) left -= chunk; } memcpy((caddr_t)va, sigcode, sz); - - (void) uvm_map_protect(kernel_map, va, round_page(sz), + r = uvm_map_protect(kernel_map, va, round_page(va + sz), PROT_READ, 0, FALSE, FALSE); + if (r) { + uao_detach(sigobject); + sigobject = NULL; + return (r); + } sigcode_va = va; sigcode_sz = round_page(sz); } @@ -927,8 +930,6 @@ exec_timekeep_map(struct process *pr) vaddr_t va = 0; timekeep_object = uao_create(timekeep_sz, 0); - uao_reference(timekeep_object); - if (uvm_map(kernel_map, &va, timekeep_sz, timekeep_object, 0, 0, UVM_MAPFLAG(PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE, MAP_INHERIT_SHARE, MADV_RANDOM, 0))) {