Commit 8d2587970b8bdf7c8d9208e3f4bb93182aef1a0f

Authored by Phil Carmody
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

... ... @@ -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