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

Reply via email to