Bug 382161 (CVE-2007-5500)

Summary: CVE-2007-5500 kernel hang via userspace PTRACE+waitid
Product: [Other] Security Response Reporter: Mark J. Cox <mjc>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: dhoward, dzickus, eteo, jmarchan, jpirko, kreilly, lwang, roland, security-response-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2009-04-06 07:29:45 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 382181, 382191, 382201, 382211, 392361    
Bug Blocks:    

Comment 2 Mark J. Cox 2007-11-14 11:29:26 UTC
Roland said:

Vanilla 2.6.9 is not affected, but RHEL4 probably is.  It has backported
the relevant changes from the later upstream code so it probably behaves
like the vanilla upstream kernel does now.

RHEL5 is probably not affected.  It has the ptrace subsystem replaced
such that I think this code path no longer involved in the cases that
can trigger the problem.


Comment 5 Mark J. Cox 2007-11-14 11:38:25 UTC
Roland wrote:

....The original "if (p->state > TASK_STOPPED)" line predated the introduction
of TASK_TRACED.  When written, it was a correct test for what we now write
as "if (p->exit_state)".  The patch below is the minimal necessary change
to restore the original sense of the test intended and correct the
pathological behavior of this test case.  This seems like the right thing
to put in right away.  (I tested it with the case you forwarded.)  That
covers the "security" problem, such as it is.  (It doesn't seem really
exploitable to me, since if you kill all the traced processes it still
dies, no permanent leaks or anything.)

Later we can get into what the check is there for at all and clean that up
right.....

---
[PATCH] wait_task_stopped: Check p->exit_state instead of TASK_TRACED

The original meaning of the old test (p->state > TASK_STOPPED) was
"not dead", since it was before TASK_TRACED existed and before the
state/exit_state split.  It was a wrong correction in commit
14bf01bb0599c89fc7f426d20353b76e12555308 to make this test for
TASK_TRACED instead.  It should have been changed when TASK_TRACED
was introducted and again when exit_state was introduced.

Signed-off-by: Roland McGrath <roland>
---
 kernel/exit.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/kernel/exit.c b/kernel/exit.c
index f1aec27..cd0f1d4 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1386,8 +1386,7 @@ static int wait_task_stopped(struct task_struct *p, int
delayed_group_leader,
 		int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
 
 		exit_code = p->exit_code;
-		if (unlikely(!exit_code) ||
-		    unlikely(p->state & TASK_TRACED))
+		if (unlikely(!exit_code) || unlikely(p->exit_state))
 			goto bail_ref;
 		return wait_noreap_copyout(p, pid, uid,
 					   why, (exit_code << 8) | 0x7f,


Comment 9 Jan Lieskovsky 2007-11-23 12:34:06 UTC
Adding this issue desription comment:

Scott James Remnant of Ubuntu reported a bug that could allow a local,
unprivileged user to cause a kernel hang.

"The spin occurs inside sys_waitid (1696..1729) when called with the
WNOWAIT option and a signal from a ptraced process to be waited upon;
the syscall never exits, so depending on the kernel state, the effect
can be anything from a process spinning to a full system hang."