diff options
author | Dmitry Shmidt <dimitrysh@google.com> | 2016-09-07 14:37:52 -0700 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2016-09-07 14:37:52 -0700 |
commit | cade80573cf8a76e46a95f8a714dd264c67bcb96 (patch) | |
tree | 7e7b236076db5b9f6630a3269d5cdc02a2adfb08 /mm/slab.c | |
parent | 5c0fc54c9b67e04d533b5ebec718d37f747a9170 (diff) | |
parent | 6b93f8214eabf0f363eab5283c2ad18b5bc33135 (diff) |
Merge remote-tracking branch 'common/android-4.4' into android-4.4.y
Diffstat (limited to 'mm/slab.c')
-rw-r--r-- | mm/slab.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/mm/slab.c b/mm/slab.c index 4765c97ce690..24a615d42d74 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -4228,6 +4228,36 @@ static int __init slab_proc_init(void) module_init(slab_proc_init); #endif +#ifdef CONFIG_HARDENED_USERCOPY +/* + * Rejects objects that are incorrectly sized. + * + * Returns NULL if check passes, otherwise const char * to name of cache + * to indicate an error. + */ +const char *__check_heap_object(const void *ptr, unsigned long n, + struct page *page) +{ + struct kmem_cache *cachep; + unsigned int objnr; + unsigned long offset; + + /* Find and validate object. */ + cachep = page->slab_cache; + objnr = obj_to_index(cachep, page, (void *)ptr); + BUG_ON(objnr >= cachep->num); + + /* Find offset within object. */ + offset = ptr - index_to_obj(cachep, page, objnr) - obj_offset(cachep); + + /* Allow address range falling entirely within object size. */ + if (offset <= cachep->object_size && n <= cachep->object_size - offset) + return NULL; + + return cachep->name; +} +#endif /* CONFIG_HARDENED_USERCOPY */ + /** * ksize - get the actual amount of memory allocated for a given object * @objp: Pointer to the object |