git: 70dd5eebc025 - main - amd64: Fix propagation of LDT updates
Mark Johnston
markj at FreeBSD.org
Mon Jun 14 21:34:35 UTC 2021
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=70dd5eebc025badb7b835dfee3915d8b5f1e7468
commit 70dd5eebc025badb7b835dfee3915d8b5f1e7468
Author: Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-06-14 21:32:18 +0000
Commit: Mark Johnston <markj at 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);
}
More information about the dev-commits-src-all
mailing list