mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
mm: Convert check_heap_object() to use struct slab
Ensure that we're not seeing a tail page inside __check_heap_object() by converting to a slab instead of a page. Take the opportunity to mark the slab as const since we're not modifying it. Also move the declaration of __check_heap_object() to mm/slab.h so it's not available to the wider kernel. [ vbabka@suse.cz: in check_heap_object() only convert to struct slab for actual PageSlab pages; use folio as intermediate step instead of page ] Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> Reviewed-by: Roman Gushchin <guro@fb.com>
This commit is contained in:
parent
7213230af5
commit
0b3eb091d5
5 changed files with 30 additions and 26 deletions
14
mm/slab.c
14
mm/slab.c
|
@ -372,8 +372,8 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp)
|
|||
static int slab_max_order = SLAB_MAX_ORDER_LO;
|
||||
static bool slab_max_order_set __initdata;
|
||||
|
||||
static inline void *index_to_obj(struct kmem_cache *cache, struct page *page,
|
||||
unsigned int idx)
|
||||
static inline void *index_to_obj(struct kmem_cache *cache,
|
||||
const struct page *page, unsigned int idx)
|
||||
{
|
||||
return page->s_mem + cache->size * idx;
|
||||
}
|
||||
|
@ -4166,8 +4166,8 @@ ssize_t slabinfo_write(struct file *file, const char __user *buffer,
|
|||
* Returns NULL if check passes, otherwise const char * to name of cache
|
||||
* to indicate an error.
|
||||
*/
|
||||
void __check_heap_object(const void *ptr, unsigned long n, struct page *page,
|
||||
bool to_user)
|
||||
void __check_heap_object(const void *ptr, unsigned long n,
|
||||
const struct slab *slab, bool to_user)
|
||||
{
|
||||
struct kmem_cache *cachep;
|
||||
unsigned int objnr;
|
||||
|
@ -4176,15 +4176,15 @@ void __check_heap_object(const void *ptr, unsigned long n, struct page *page,
|
|||
ptr = kasan_reset_tag(ptr);
|
||||
|
||||
/* Find and validate object. */
|
||||
cachep = page->slab_cache;
|
||||
objnr = obj_to_index(cachep, page, (void *)ptr);
|
||||
cachep = slab->slab_cache;
|
||||
objnr = obj_to_index(cachep, slab_page(slab), (void *)ptr);
|
||||
BUG_ON(objnr >= cachep->num);
|
||||
|
||||
/* Find offset within object. */
|
||||
if (is_kfence_address(ptr))
|
||||
offset = ptr - kfence_object_start(ptr);
|
||||
else
|
||||
offset = ptr - index_to_obj(cachep, page, objnr) - obj_offset(cachep);
|
||||
offset = ptr - index_to_obj(cachep, slab_page(slab), objnr) - obj_offset(cachep);
|
||||
|
||||
/* Allow address range falling entirely within usercopy region. */
|
||||
if (offset >= cachep->useroffset &&
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue