• Paul Menage's avatar
    cgroups: fix a race between rmdir and remount · 307257cf
    Paul Menage authored
    When a cgroup is removed, it's unlinked from its parent's children list,
    but not actually freed until the last dentry on it is released (at which
    point cgrp->root->number_of_cgroups is decremented).
    
    Currently rebind_subsystems checks for the top cgroup's child list being
    empty in order to rebind subsystems into or out of a hierarchy - this can
    result in the set of subsystems bound to a hierarchy being
    removed-but-not-freed cgroup.
    
    The simplest fix for this is to forbid remounts that change the set of
    subsystems on a hierarchy that has removed-but-not-freed cgroups.  This
    bug can be reproduced via:
    
    mkdir /mnt/cg
    mount -t cgroup -o ns,freezer cgroup /mnt/cg
    mkdir /mnt/cg/foo
    sleep 1h < /mnt/cg/foo &
    rmdir /mnt/cg/foo
    mount -t cgroup -o remount,ns,devices,freezer cgroup /mnt/cg
    kill $!
    
    Though the above will cause oops in -mm only but not mainline, but the bug
    can cause memory leak in mainline (and even oops)
    Signed-off-by: default avatarPaul Menage <menage@google.com>
    Reviewed-by: default avatarLi Zefan <lizf@cn.fujitsu.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    307257cf
cgroup.c 82.9 KB