summaryrefslogtreecommitdiffstats
path: root/sys/i386/linux
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2004-10-01 05:01:00 +0000
committerdas <das@FreeBSD.org>2004-10-01 05:01:00 +0000
commit81fc7cf4858181b5112087c818ade372e1a94828 (patch)
treed2985aee9d405619c13527b419a3fc39966ff997 /sys/i386/linux
parent6bd373b4fac67fc72afa0199446e9b9dcd983f41 (diff)
downloadFreeBSD-src-81fc7cf4858181b5112087c818ade372e1a94828.zip
FreeBSD-src-81fc7cf4858181b5112087c818ade372e1a94828.tar.gz
Fix the following race:
1. Process p1 is currently being swapped in. 2. Process p2 calls linux_ptrace(PTRACE_GETFPXREGS, p1_pid, ...) 3. After acquiring a reference to FIRST_THREAD_IN_PROC(p1), p2 blocks in faultin() while p1 finishes being swapped in. This means p2 won't get back the lock on p1 until after p1's threads are runnable. 4. After p1 is swapped in, the first thread in p1 exits. 5. p2 now uses its dangling reference to p1's first thread.
Diffstat (limited to 'sys/i386/linux')
-rw-r--r--sys/i386/linux/linux_ptrace.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/i386/linux/linux_ptrace.c b/sys/i386/linux/linux_ptrace.c
index 9cee441..6d61ce4 100644
--- a/sys/i386/linux/linux_ptrace.c
+++ b/sys/i386/linux/linux_ptrace.c
@@ -386,9 +386,9 @@ linux_ptrace(struct thread *td, struct linux_ptrace_args *uap)
goto fail;
}
- td2 = FIRST_THREAD_IN_PROC(p);
if (req == PTRACE_GETFPXREGS) {
- _PHOLD(p);
+ _PHOLD(p); /* may block */
+ td2 = FIRST_THREAD_IN_PROC(p);
error = linux_proc_read_fpxregs(td2, &r.fpxreg);
_PRELE(p);
PROC_UNLOCK(p);
@@ -398,7 +398,8 @@ linux_ptrace(struct thread *td, struct linux_ptrace_args *uap)
} else {
/* clear dangerous bits exactly as Linux does*/
r.fpxreg.mxcsr &= 0xffbf;
- _PHOLD(p);
+ _PHOLD(p); /* may block */
+ td2 = FIRST_THREAD_IN_PROC(p);
error = linux_proc_write_fpxregs(td2, &r.fpxreg);
_PRELE(p);
PROC_UNLOCK(p);
OpenPOWER on IntegriCloud