提交 4a46412a 编写于 作者: P Peng Liu 提交者: Zheng Zengkai

kfence: Fix wrong size of alloc_covered when enable dynamic

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4V388
CVE: NA

--------------------------------

Patch "kfence: Add a module parameter to adjust kfence objects"
enable dynamic configuration of the number of KFENCE guarded
objects, but the size of alloc_covered is not the same with the
original kfence. This is because const_ilog2 is just valid for
a constant, and KFENCE_NR_OBJECTS is not a constant when enabling
dynamic configuration.

This difference between original kfence will lead to a confusion
loggic in the process of skipping covered path. In a arm64 machine,
the following panic is observed.

  Call trace:
   __kfence_alloc+0x378/0x780
   kmem_cache_alloc+0x204/0x614
   getname_kernel+0x38/0xf4
   filp_open+0x2c/0x6c
   populate_rootfs+0xcc/0x174
   do_one_initcall+0xac/0x20c
   kernel_init_freeable+0x380/0x3c8
   kernel_init+0x18/0xf0
   ret_from_fork+0x10/0x18
  Code: 54000080 a9400381 f9000420 f9000001 (f900039c)
  ---[ end trace 814fe40d608e1b74 ]---
  Kernel panic - not syncing: TLB conflict abort: Fatal exception

To fix this, ilog2 is used to replace const_ilog2 when enable
dynamic configuration of KFENCE guarded objects.

Fixes: 901b983c ("kfence: Add a module parameter to adjust kfence objects")
Signed-off-by: NPeng Liu <liupeng256@huawei.com>
Reviewed-by: NKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 c947ee58
......@@ -146,6 +146,8 @@ module_param_cb(num_objects, &num_objects_param_ops, &kfence_num_objects, 0600);
* backing pages (in __kfence_pool).
*/
#ifdef CONFIG_KFENCE_DYNAMIC_OBJECTS
#define ILOG2(x) (ilog2((x)))
struct kfence_metadata *kfence_metadata;
static phys_addr_t metadata_size;
......@@ -155,6 +157,8 @@ static inline bool kfence_metadata_valid(void)
}
#else
#define ILOG2(x) (const_ilog2((x)))
static_assert(CONFIG_KFENCE_NUM_OBJECTS > 0);
struct kfence_metadata kfence_metadata[CONFIG_KFENCE_NUM_OBJECTS];
......@@ -185,7 +189,7 @@ atomic_t kfence_allocation_gate = ATOMIC_INIT(1);
* P(alloc_traces) = (1 - e^(-HNUM * (alloc_traces / SIZE)) ^ HNUM
*/
#define ALLOC_COVERED_HNUM 2
#define ALLOC_COVERED_ORDER (const_ilog2(KFENCE_NR_OBJECTS) + 2)
#define ALLOC_COVERED_ORDER (ILOG2(KFENCE_NR_OBJECTS) + 2)
#define ALLOC_COVERED_SIZE (1 << ALLOC_COVERED_ORDER)
#define ALLOC_COVERED_HNEXT(h) hash_32(h, ALLOC_COVERED_ORDER)
#define ALLOC_COVERED_MASK (ALLOC_COVERED_SIZE - 1)
......@@ -831,7 +835,7 @@ static int __init kfence_dynamic_init(void)
return -ENOMEM;
}
covered_size = sizeof(atomic_t) * KFENCE_NR_OBJECTS;
covered_size = sizeof(atomic_t) * ALLOC_COVERED_SIZE;
alloc_covered = memblock_alloc(covered_size, PAGE_SIZE);
if (!alloc_covered) {
memblock_free((phys_addr_t)kfence_metadata, metadata_size);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册