The branch stable/13 has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=4a77ce73eadfe7ceddc3f2330028880b886401fd

commit 4a77ce73eadfe7ceddc3f2330028880b886401fd
Author:     Mark Johnston <[email protected]>
AuthorDate: 2021-06-14 21:32:18 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2021-06-21 13:13:20 +0000

    amd64: Fix propagation of LDT updates
    
    When a process has used sysarch(2) to specify descriptors for its
    private LDT, upon rfork(RFMEM) descriptors are copied into the new child
    process.  Any updates to the descriptors are thus reflected to all other
    processes sharing the vmspace.  However, this is incorrect in the rather
    obscure case where the child process was created before the LDT was
    modified.  Fix this by only modifying other processes which already
    share the LDT.
    
    Reported by:    syzkaller
    Reviewed by:    kib
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 70dd5eebc025badb7b835dfee3915d8b5f1e7468)
---
 sys/amd64/amd64/sys_machdep.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c
index 5a0145e76ccd..c10b15896132 100644
--- a/sys/amd64/amd64/sys_machdep.c
+++ b/sys/amd64/amd64/sys_machdep.c
@@ -492,15 +492,19 @@ set_user_ldt(struct mdproc *mdp)
 }
 
 static void
-set_user_ldt_rv(struct vmspace *vmsp)
+set_user_ldt_rv(void *arg)
 {
-       struct thread *td;
+       struct proc *orig, *target;
+       struct proc_ldt *ldt;
+
+       orig = arg;
+       target = curthread->td_proc;
 
-       td = curthread;
-       if (vmsp != td->td_proc->p_vmspace)
+       ldt = (void *)atomic_load_acq_ptr((uintptr_t *)&orig->p_md.md_ldt);
+       if (target->p_md.md_ldt != ldt)
                return;
 
-       set_user_ldt(&td->td_proc->p_md);
+       set_user_ldt(&target->p_md);
 }
 
 struct proc_ldt *
@@ -550,8 +554,7 @@ user_ldt_alloc(struct proc *p, int force)
        atomic_thread_fence_rel();
        mdp->md_ldt = new_ldt;
        critical_exit();
-       smp_rendezvous(NULL, (void (*)(void *))set_user_ldt_rv, NULL,
-           p->p_vmspace);
+       smp_rendezvous(NULL, set_user_ldt_rv, NULL, p);
 
        return (mdp->md_ldt);
 }
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to