On Mon, Feb 10, 2025 at 09:45:46AM -0700, Theo de Raadt wrote: > CVSROOT: /cvs > Module name: src > Changes by: dera...@cvs.openbsd.org 2025/02/10 09:45:46 > > Modified files: > sys/sys : proc.h > sys/kern : kern_event.c kern_pledge.c > sys/dev/vmm : vmm.c > > Log message: > A syzkaller report was diagnosed by semarie, and found a namei-related > sleeping system call which was re-inspecting p->p_p->ps_pledge in one thread, > after another thread had reduced the promises by calling pledge(), with > promises which would have prevented that syscall from being called in > the first place. This inconsistant promise view is dangerous. So let's > change pledge semantics a tiny bit: We copy the per-process p_p->ps_pledge > value to per-thread p_pledge at invocation of each system call, so that the > configuration is stable. > This method avoids increasing the cost of pledge checks. > ok claudio kettenis semarie
This broke regress/sys/kern/pledge/execpromise. Keeping the new p_pledge proc field in sync upon exec fixes the regression. diff --git sys/kern/kern_exec.c sys/kern/kern_exec.c index de95acf6b190..4e278920c7d3 100644 --- sys/kern/kern_exec.c +++ sys/kern/kern_exec.c @@ -572,11 +572,13 @@ sys_execve(struct proc *p, void *v, register_t *retval) atomic_clearbits_int(&pr->ps_flags, PS_SUGIDEXEC); if (pr->ps_flags & PS_EXECPLEDGE) { + p->p_pledge = pr->ps_execpledge; pr->ps_pledge = pr->ps_execpledge; atomic_setbits_int(&pr->ps_flags, PS_PLEDGE); } else { atomic_clearbits_int(&pr->ps_flags, PS_PLEDGE); pr->ps_pledge = 0; + p->p_pledge = 0; /* XXX XXX XXX XXX */ /* Clear our unveil paths out so the child * starts afresh