Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Jun 2021 21:34:35 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 70dd5eebc025 - main - amd64: Fix propagation of LDT updates
Message-ID:  <202106142134.15ELYZpJ067457@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=70dd5eebc025badb7b835dfee3915d8b5f1e7468

commit 70dd5eebc025badb7b835dfee3915d8b5f1e7468
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-06-14 21:32:18 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-06-14 21:32:18 +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
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
---
 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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202106142134.15ELYZpJ067457>