• R
    mm: memcg/slab: fix racy access to page->mem_cgroup in mem_cgroup_from_obj() · 19b629c9
    Roman Gushchin 提交于
    mem_cgroup_from_obj() checks the lowest bit of the page->mem_cgroup
    pointer to determine if the page has an attached obj_cgroup vector instead
    of a regular memcg pointer.  If it's not set, it simple returns the
    page->mem_cgroup value as a struct mem_cgroup pointer.
    
    The commit 10befea9 ("mm: memcg/slab: use a single set of kmem_caches
    for all allocations") changed the moment when this bit is set: if
    previously it was set on the allocation of the slab page, now it can be
    set well after, when the first accounted object is allocated on this page.
    
    It opened a race: if page->mem_cgroup is set concurrently after the first
    page_has_obj_cgroups(page) check, a pointer to the obj_cgroups array can
    be returned as a memory cgroup pointer.
    
    A simple check for page->mem_cgroup pointer for NULL before the
    page_has_obj_cgroups() check fixes the race.  Indeed, if the pointer is
    not NULL, it's either a simple mem_cgroup pointer or a pointer to
    obj_cgroup vector.  The pointer can be asynchronously changed from NULL to
    (obj_cgroup_vec | 0x1UL), but can't be changed from a valid memcg pointer
    to objcg vector or back.
    
    If the object passed to mem_cgroup_from_obj() is a slab object and
    page->mem_cgroup is NULL, it means that the object is not accounted, so
    the function must return NULL.
    
    I've discovered the race looking at the code, so far I haven't seen it in
    the wild.
    
    Fixes: 10befea9 ("mm: memcg/slab: use a single set of kmem_caches for all allocations")
    Signed-off-by: NRoman Gushchin <guro@fb.com>
    Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
    Reviewed-by: NShakeel Butt <shakeelb@google.com>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: Vlastimil Babka <vbabka@suse.cz>
    Link: https://lkml.kernel.org/r/20200910022435.2773735-1-guro@fb.comSigned-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
    19b629c9
memcontrol.c 190.3 KB