Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

slab: Generify kernel pointer validation

As suggested by Linus, introduce a kern_ptr_validate() helper that does some
sanity checks to make sure a pointer is a valid kernel pointer. This is a
preparational step for fixing SLUB kmem_ptr_validate().

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Christoph Lameter <cl@linux-foundation.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Matt Mackall <mpm@selenic.com>
Cc: Nick Piggin <npiggin@suse.de>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Pekka Enberg and committed by
Linus Torvalds
fc1c1833 4dc86ae1

+23 -12
+1
include/linux/slab.h
··· 106 106 void kmem_cache_free(struct kmem_cache *, void *); 107 107 unsigned int kmem_cache_size(struct kmem_cache *); 108 108 const char *kmem_cache_name(struct kmem_cache *); 109 + int kern_ptr_validate(const void *ptr, unsigned long size); 109 110 int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr); 110 111 111 112 /*
+1 -12
mm/slab.c
··· 3602 3602 */ 3603 3603 int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr) 3604 3604 { 3605 - unsigned long addr = (unsigned long)ptr; 3606 - unsigned long min_addr = PAGE_OFFSET; 3607 - unsigned long align_mask = BYTES_PER_WORD - 1; 3608 3605 unsigned long size = cachep->buffer_size; 3609 3606 struct page *page; 3610 3607 3611 - if (unlikely(addr < min_addr)) 3612 - goto out; 3613 - if (unlikely(addr > (unsigned long)high_memory - size)) 3614 - goto out; 3615 - if (unlikely(addr & align_mask)) 3616 - goto out; 3617 - if (unlikely(!kern_addr_valid(addr))) 3618 - goto out; 3619 - if (unlikely(!kern_addr_valid(addr + size - 1))) 3608 + if (unlikely(!kern_ptr_validate(ptr, size))) 3620 3609 goto out; 3621 3610 page = virt_to_page(ptr); 3622 3611 if (unlikely(!PageSlab(page)))
+21
mm/util.c
··· 186 186 } 187 187 EXPORT_SYMBOL(kzfree); 188 188 189 + int kern_ptr_validate(const void *ptr, unsigned long size) 190 + { 191 + unsigned long addr = (unsigned long)ptr; 192 + unsigned long min_addr = PAGE_OFFSET; 193 + unsigned long align_mask = sizeof(void *) - 1; 194 + 195 + if (unlikely(addr < min_addr)) 196 + goto out; 197 + if (unlikely(addr > (unsigned long)high_memory - size)) 198 + goto out; 199 + if (unlikely(addr & align_mask)) 200 + goto out; 201 + if (unlikely(!kern_addr_valid(addr))) 202 + goto out; 203 + if (unlikely(!kern_addr_valid(addr + size - 1))) 204 + goto out; 205 + return 1; 206 + out: 207 + return 0; 208 + } 209 + 189 210 /* 190 211 * strndup_user - duplicate an existing string from user space 191 212 * @s: The string to duplicate