diff options
author | Li Zefan <lizf@cn.fujitsu.com> | 2008-11-07 00:05:48 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-11-13 09:55:55 -0800 |
commit | 880eaf154bc95220798e85802cdd9cb6534ee7a7 (patch) | |
tree | 6f681cd5e143913def4ddb22b2e50a0ca620f07e | |
parent | c27c4b666ddf7a36b6f20c9b809217157496b36b (diff) |
cgroups: fix invalid cgrp->dentry before cgroup has been completely removed
commit 24eb089950ce44603b30a3145a2c8520e2b55bb1 upstream
This fixes an oops when reading /proc/sched_debug.
A cgroup won't be removed completely until finishing cgroup_diput(), so we
shouldn't invalidate cgrp->dentry in cgroup_rmdir(). Otherwise, when a
group is being removed while cgroup_path() gets called, we may trigger
NULL dereference BUG.
The bug can be reproduced:
# cat test.sh
#!/bin/sh
mount -t cgroup -o cpu xxx /mnt
for (( ; ; ))
{
mkdir /mnt/sub
rmdir /mnt/sub
}
# ./test.sh &
# cat /proc/sched_debug
BUG: unable to handle kernel NULL pointer dereference at 00000038
IP: [<c045a47f>] cgroup_path+0x39/0x90
..
Call Trace:
[<c0420344>] ? print_cfs_rq+0x6e/0x75d
[<c0421160>] ? sched_debug_show+0x72d/0xc1e
..
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Acked-by: Paul Menage <menage@google.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | kernel/cgroup.c | 1 |
1 files changed, 0 insertions, 1 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index a0123d75ec9..d68bf2bc5ca 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2443,7 +2443,6 @@ static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) list_del(&cgrp->sibling); spin_lock(&cgrp->dentry->d_lock); d = dget(cgrp->dentry); - cgrp->dentry = NULL; spin_unlock(&d->d_lock); cgroup_d_remove_dir(d); |