waitid (..., WNOWAIT) spins or hangs the kernel inside sys_waitid if the queued event is from ptrace
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux-source-2.6.15 (Ubuntu) |
Fix Released
|
Medium
|
Kees Cook | ||
linux-source-2.6.17 (Ubuntu) |
Fix Released
|
Medium
|
Kees Cook | ||
linux-source-2.6.20 (Ubuntu) |
Fix Released
|
Medium
|
Kees Cook | ||
linux-source-2.6.22 (Ubuntu) |
Fix Released
|
Medium
|
Kees Cook |
Bug Description
Binary package hint: linux-source-2.6.22
waitid () is an improved wait system call added since Linux 2.6.9 that returns a siginfo structure for each event, rather than random bit fields trying to squash everything together. One of its more interesting options is WNOWAIT which returns the siginfo, but leaves the child in a waitable state so that a further call will return the same information (usually this further call is without WNOWAIT).
This has various uses, for example catching SIGCHLD and leaving the process in the table so that /proc/$PID can be examined before the process is finally reaped.
This normally works fine. However if the wait queue item is generated by ptrace, bad things happen. I've seen the process simple spinning at 100% CPU inside sys_waitid () and I've seen the machine stop responding completely -- sometimes if X is running, it behaves as if /dev/console has been closed (newlines get inserted repeatedly into the running application).
CVE References
Changed in linux-source-2.6.22: | |
assignee: | nobody → keescook |
status: | New → In Progress |
Changed in linux-source-2.6.22: | |
status: | Triaged → Fix Committed |
Changed in linux-source-2.6.20: | |
status: | Triaged → Fix Committed |
Changed in linux-source-2.6.17: | |
status: | Triaged → Fix Committed |
Changed in linux-source-2.6.15: | |
status: | Triaged → Fix Committed |
Changed in linux-source-2.6.17: | |
status: | Fix Committed → Fix Released |
Changed in linux-source-2.6.20: | |
status: | Fix Committed → Fix Released |
Changed in linux-source-2.6.22: | |
status: | Fix Committed → Fix Released |
Changed in linux-source-2.6.15: | |
status: | Fix Committed → Fix Released |
This small program demonstrates the failure.
It spawns a child which issues PTRACE_TRACEME and then raises SIGSTOP (which will be trapped by the parent).
The parent waits for the child with WNOWAIT to get the details early, this will spin at 100% CPU.
Remove the "| WNOWAIT" (and the additional waitid call just below) and it will work as expected.