Commit 8d2587970b8bdf7c8d9208e3f4bb93182aef1a0f
Committed by
Linus Torvalds
1 parent
edd45544c6
cgroups: if you list_empty() a head then don't list_del() it
list_del() leaves poison in the prev and next pointers. The next list_empty() will compare those poisons, and say the list isn't empty. Any list operations that assume the node is on a list because of such a check will be fooled into dereferencing poison. One needs to INIT the node after the del, and fortunately there's already a wrapper for that - list_del_init(). Some of the dels are followed by deallocations, so can be ignored, and one can be merged with an add to make a move. Apart from that, I erred on the side of caution in making nodes list_empty()-queriable. Signed-off-by: Phil Carmody <ext-phil.2.carmody@nokia.com> Reviewed-by: Paul Menage <menage@google.com> Cc: Li Zefan <lizf@cn.fujitsu.com> Acked-by: Kirill A. Shutemov <kirill@shutemov.name> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 6 additions and 8 deletions Side-by-side Diff
kernel/cgroup.c
... | ... | @@ -1813,10 +1813,8 @@ |
1813 | 1813 | |
1814 | 1814 | /* Update the css_set linked lists if we're using them */ |
1815 | 1815 | write_lock(&css_set_lock); |
1816 | - if (!list_empty(&tsk->cg_list)) { | |
1817 | - list_del(&tsk->cg_list); | |
1818 | - list_add(&tsk->cg_list, &newcg->tasks); | |
1819 | - } | |
1816 | + if (!list_empty(&tsk->cg_list)) | |
1817 | + list_move(&tsk->cg_list, &newcg->tasks); | |
1820 | 1818 | write_unlock(&css_set_lock); |
1821 | 1819 | |
1822 | 1820 | for_each_subsys(root, ss) { |
1823 | 1821 | |
... | ... | @@ -3655,12 +3653,12 @@ |
3655 | 3653 | spin_lock(&release_list_lock); |
3656 | 3654 | set_bit(CGRP_REMOVED, &cgrp->flags); |
3657 | 3655 | if (!list_empty(&cgrp->release_list)) |
3658 | - list_del(&cgrp->release_list); | |
3656 | + list_del_init(&cgrp->release_list); | |
3659 | 3657 | spin_unlock(&release_list_lock); |
3660 | 3658 | |
3661 | 3659 | cgroup_lock_hierarchy(cgrp->root); |
3662 | 3660 | /* delete this cgroup from parent->children */ |
3663 | - list_del(&cgrp->sibling); | |
3661 | + list_del_init(&cgrp->sibling); | |
3664 | 3662 | cgroup_unlock_hierarchy(cgrp->root); |
3665 | 3663 | |
3666 | 3664 | d = dget(cgrp->dentry); |
... | ... | @@ -3879,7 +3877,7 @@ |
3879 | 3877 | subsys[ss->subsys_id] = NULL; |
3880 | 3878 | |
3881 | 3879 | /* remove subsystem from rootnode's list of subsystems */ |
3882 | - list_del(&ss->sibling); | |
3880 | + list_del_init(&ss->sibling); | |
3883 | 3881 | |
3884 | 3882 | /* |
3885 | 3883 | * disentangle the css from all css_sets attached to the dummytop. as |
... | ... | @@ -4241,7 +4239,7 @@ |
4241 | 4239 | if (!list_empty(&tsk->cg_list)) { |
4242 | 4240 | write_lock(&css_set_lock); |
4243 | 4241 | if (!list_empty(&tsk->cg_list)) |
4244 | - list_del(&tsk->cg_list); | |
4242 | + list_del_init(&tsk->cg_list); | |
4245 | 4243 | write_unlock(&css_set_lock); |
4246 | 4244 | } |
4247 | 4245 |