Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Jun 2021 14:22:05 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 4a77ce73eadf - stable/13 - amd64: Fix propagation of LDT updates
Message-ID:  <202106211422.15LEM5jt058063@gitrepo.freebsd.org>

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

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

commit 4a77ce73eadfe7ceddc3f2330028880b886401fd
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-06-14 21:32:18 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
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);
 }



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