mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
Merge 60115fa54a ("mm: defer kmemleak object creation of module_alloc()") into android-mainline
Steps on the way to 5.17-rc1 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I2ec342d4b0cd04807ed02da5262c92bdcaa6d8fd
This commit is contained in:
@@ -36,7 +36,7 @@ void *module_alloc(unsigned long size)
|
||||
module_alloc_end = MODULES_END;
|
||||
|
||||
p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
|
||||
module_alloc_end, gfp_mask, PAGE_KERNEL, 0,
|
||||
module_alloc_end, gfp_mask, PAGE_KERNEL, VM_DEFER_KMEMLEAK,
|
||||
NUMA_NO_NODE, __builtin_return_address(0));
|
||||
|
||||
if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
|
||||
@@ -58,7 +58,7 @@ void *module_alloc(unsigned long size)
|
||||
PAGE_KERNEL, 0, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
|
||||
if (p && (kasan_module_alloc(p, size) < 0)) {
|
||||
if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {
|
||||
vfree(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -37,14 +37,15 @@
|
||||
|
||||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
gfp_t gfp_mask = GFP_KERNEL;
|
||||
void *p;
|
||||
|
||||
if (PAGE_ALIGN(size) > MODULES_LEN)
|
||||
return NULL;
|
||||
p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END,
|
||||
GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
|
||||
gfp_mask, PAGE_KERNEL_EXEC, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
if (p && (kasan_module_alloc(p, size) < 0)) {
|
||||
if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {
|
||||
vfree(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ static unsigned long int get_module_load_offset(void)
|
||||
|
||||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
gfp_t gfp_mask = GFP_KERNEL;
|
||||
void *p;
|
||||
|
||||
if (PAGE_ALIGN(size) > MODULES_LEN)
|
||||
@@ -74,10 +75,10 @@ void *module_alloc(unsigned long size)
|
||||
|
||||
p = __vmalloc_node_range(size, MODULE_ALIGN,
|
||||
MODULES_VADDR + get_module_load_offset(),
|
||||
MODULES_END, GFP_KERNEL,
|
||||
PAGE_KERNEL, 0, NUMA_NO_NODE,
|
||||
MODULES_END, gfp_mask,
|
||||
PAGE_KERNEL, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
if (p && (kasan_module_alloc(p, size) < 0)) {
|
||||
if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {
|
||||
vfree(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -475,12 +475,12 @@ static inline void kasan_populate_early_vm_area_shadow(void *start,
|
||||
* allocations with real shadow memory. With KASAN vmalloc, the special
|
||||
* case is unnecessary, as the work is handled in the generic case.
|
||||
*/
|
||||
int kasan_module_alloc(void *addr, size_t size);
|
||||
int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask);
|
||||
void kasan_free_shadow(const struct vm_struct *vm);
|
||||
|
||||
#else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
|
||||
|
||||
static inline int kasan_module_alloc(void *addr, size_t size) { return 0; }
|
||||
static inline int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask) { return 0; }
|
||||
static inline void kasan_free_shadow(const struct vm_struct *vm) {}
|
||||
|
||||
#endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
|
||||
|
||||
@@ -28,6 +28,13 @@ struct notifier_block; /* in notifier.h */
|
||||
#define VM_MAP_PUT_PAGES 0x00000200 /* put pages and free array in vfree */
|
||||
#define VM_NO_HUGE_VMAP 0x00000400 /* force PAGE_SIZE pte mapping */
|
||||
|
||||
#if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \
|
||||
!defined(CONFIG_KASAN_VMALLOC)
|
||||
#define VM_DEFER_KMEMLEAK 0x00000800 /* defer kmemleak object creation */
|
||||
#else
|
||||
#define VM_DEFER_KMEMLEAK 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VM_KASAN is used slightly differently depending on CONFIG_KASAN_VMALLOC.
|
||||
*
|
||||
|
||||
@@ -498,7 +498,7 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
|
||||
|
||||
#else /* CONFIG_KASAN_VMALLOC */
|
||||
|
||||
int kasan_module_alloc(void *addr, size_t size)
|
||||
int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask)
|
||||
{
|
||||
void *ret;
|
||||
size_t scaled_size;
|
||||
@@ -520,9 +520,14 @@ int kasan_module_alloc(void *addr, size_t size)
|
||||
__builtin_return_address(0));
|
||||
|
||||
if (ret) {
|
||||
struct vm_struct *vm = find_vm_area(addr);
|
||||
__memset(ret, KASAN_SHADOW_INIT, shadow_size);
|
||||
find_vm_area(addr)->flags |= VM_KASAN;
|
||||
vm->flags |= VM_KASAN;
|
||||
kmemleak_ignore(ret);
|
||||
|
||||
if (vm->flags & VM_DEFER_KMEMLEAK)
|
||||
kmemleak_vmalloc(vm, size, gfp_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -3074,7 +3074,8 @@ again:
|
||||
clear_vm_uninitialized_flag(area);
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
kmemleak_vmalloc(area, size, gfp_mask);
|
||||
if (!(vm_flags & VM_DEFER_KMEMLEAK))
|
||||
kmemleak_vmalloc(area, size, gfp_mask);
|
||||
|
||||
return addr;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user