Files
linux/include/linux
Vladimir Davydov 8135be5a80 memcg: fix possible use-after-free in memcg_kmem_get_cache()
Suppose task @t that belongs to a memory cgroup @memcg is going to
allocate an object from a kmem cache @c.  The copy of @c corresponding to
@memcg, @mc, is empty.  Then if kmem_cache_alloc races with the memory
cgroup destruction we can access the memory cgroup's copy of the cache
after it was destroyed:

CPU0				CPU1
----				----
[ current=@t
  @mc->memcg_params->nr_pages=0 ]

kmem_cache_alloc(@c):
  call memcg_kmem_get_cache(@c);
  proceed to allocation from @mc:
    alloc a page for @mc:
      ...

				move @t from @memcg
				destroy @memcg:
				  mem_cgroup_css_offline(@memcg):
				    memcg_unregister_all_caches(@memcg):
				      kmem_cache_destroy(@mc)

    add page to @mc

We could fix this issue by taking a reference to a per-memcg cache, but
that would require adding a per-cpu reference counter to per-memcg caches,
which would look cumbersome.

Instead, let's take a reference to a memory cgroup, which already has a
per-cpu reference counter, in the beginning of kmem_cache_alloc to be
dropped in the end, and move per memcg caches destruction from css offline
to css free.  As a side effect, per-memcg caches will be destroyed not one
by one, but all at once when the last page accounted to the memory cgroup
is freed.  This doesn't sound as a high price for code readability though.

Note, this patch does add some overhead to the kmem_cache_alloc hot path,
but it is pretty negligible - it's just a function call plus a per cpu
counter decrement, which is comparable to what we already have in
memcg_kmem_get_cache.  Besides, it's only relevant if there are memory
cgroups with kmem accounting enabled.  I don't think we can find a way to
handle this race w/o it, because alloc_page called from kmem_cache_alloc
may sleep so we can't flush all pending kmallocs w/o reference counting.

Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Acked-by: Christoph Lameter <cl@linux.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2014-12-13 12:42:49 -08:00
..
2014-09-22 16:48:47 +09:00
2014-11-30 20:13:13 -08:00
2014-11-24 17:24:08 -05:00
2014-12-08 20:00:44 +01:00
2014-11-19 13:01:26 -05:00
2014-10-03 15:28:18 -06:00
2014-10-14 09:00:44 -06:00
2014-11-12 11:16:09 +01:00
2014-08-01 22:35:55 +08:00
2014-11-04 17:34:15 -08:00
2014-10-09 11:35:48 +03:00
2014-10-08 16:01:41 -04:00
2014-08-07 14:40:08 -04:00
2014-12-13 12:42:45 -08:00
2014-08-06 18:01:24 -07:00
2014-09-25 16:07:15 +02:00
2014-09-29 15:37:01 -04:00
2014-09-01 13:48:59 +02:00
2014-11-04 14:53:36 +01:00
2014-12-10 17:41:10 -08:00
2014-10-09 22:25:58 -04:00
2014-10-24 00:14:36 +02:00
2014-11-25 16:38:32 -05:00
2014-11-25 16:38:32 -05:00
2014-11-25 16:38:32 -05:00
2014-11-04 13:29:38 +00:00
2014-08-26 13:45:56 -04:00
2014-12-08 20:00:44 +01:00
2014-12-08 20:00:44 +01:00
2014-08-08 15:57:26 -07:00
2014-08-08 15:57:31 -07:00
2014-08-08 15:57:24 -07:00
2014-12-09 16:29:11 -05:00
2014-09-23 21:40:48 -07:00
2014-08-08 15:57:22 -07:00
2014-11-28 16:08:16 +01:00
2014-09-16 15:02:55 -06:00
2014-12-09 12:05:24 +02:00
2014-12-09 21:42:00 +02:00