kallsyms_show_value return false if KALLSYMS is disabled, but its usage is done by module.c also. Thus when KALLSYMS is disabled, system will not print module load address: Earlier: ======= / # insmod test.ko / # lsmod test 12288 0 - Live 0x0000000000000000 (O) // No Module Load address / # With change: ========== / # insmod test.ko / # lsmod test 12288 0 - Live 0xffff800000fc0000 (O) // Module address / # cat /proc/modules test 12288 0 - Live 0xffff800000fc0000 (O) New file knosyms.c is added (name suggested by Kees Cook), which includes common defination irrespective of CONFIG_KALLSYMS. BPF code has high dependency on kallsyms, so bpf_dump_raw_ok check is not changed. Co-developed-by: Onkarnath <onkarnath.1@xxxxxxxxxxx> Signed-off-by: Onkarnath <onkarnath.1@xxxxxxxxxxx> Signed-off-by: Maninder Singh <maninder1.s@xxxxxxxxxxx> --- BPF logic is not changed and seems kprobe will work, rest kprobe maintainer can comment if it can cause issue. Tested for modules data. earlier conversations:(then it has dependancy on other change, but that was stashed from linux-next, now it can be pushed) https://lkml.org/lkml/2022/5/11/212 https://lkml.org/lkml/2022/4/13/47 include/linux/filter.h | 7 ++++++ include/linux/kallsyms.h | 10 +++----- kernel/Makefile | 2 +- kernel/kallsyms.c | 35 --------------------------- kernel/knosyms.c | 52 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 43 deletions(-) create mode 100644 kernel/knosyms.c diff --git a/include/linux/filter.h b/include/linux/filter.h index bbce89937fde..f67010e7c6fe 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -923,6 +923,7 @@ bool bpf_jit_supports_kfunc_call(void); bool bpf_jit_supports_far_kfunc_call(void); bool bpf_helper_changes_pkt_data(void *func); +#ifdef CONFIG_KALLSYMS static inline bool bpf_dump_raw_ok(const struct cred *cred) { /* Reconstruction of call-sites is dependent on kallsyms, @@ -930,6 +931,12 @@ static inline bool bpf_dump_raw_ok(const struct cred *cred) */ return kallsyms_show_value(cred); } +#else +static inline bool bpf_dump_raw_ok(const struct cred *cred) +{ + return false; +} +#endif struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off, const struct bpf_insn *patch, u32 len); diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index fe3c9993b5bf..3f3559ba0c56 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -24,6 +24,9 @@ struct cred; struct module; +/* How and when do we show kallsyms values? */ +extern bool kallsyms_show_value(const struct cred *cred); + static inline int is_kernel_text(unsigned long addr) { if (__is_kernel_text(addr)) @@ -95,8 +98,6 @@ extern int sprint_backtrace_build_id(char *buffer, unsigned long address); int lookup_symbol_name(unsigned long addr, char *symname); int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name); -/* How and when do we show kallsyms values? */ -extern bool kallsyms_show_value(const struct cred *cred); #else /* !CONFIG_KALLSYMS */ @@ -160,11 +161,6 @@ static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, u return -ERANGE; } -static inline bool kallsyms_show_value(const struct cred *cred) -{ - return false; -} - static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *, unsigned long), void *data) { diff --git a/kernel/Makefile b/kernel/Makefile index b69c95315480..76efc634b1a4 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -10,7 +10,7 @@ obj-y = fork.o exec_domain.o panic.o \ extable.o params.o \ kthread.o sys_ni.o nsproxy.o \ notifier.o ksysfs.o cred.o reboot.o \ - async.o range.o smpboot.o ucount.o regset.o + async.o range.o smpboot.o ucount.o regset.o knosyms.o obj-$(CONFIG_USERMODE_DRIVER) += usermode_driver.o obj-$(CONFIG_MULTIUSER) += groups.o diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 77747391f49b..1dcb7051f852 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -961,41 +961,6 @@ late_initcall(bpf_ksym_iter_register); #endif /* CONFIG_BPF_SYSCALL */ -static inline int kallsyms_for_perf(void) -{ -#ifdef CONFIG_PERF_EVENTS - extern int sysctl_perf_event_paranoid; - if (sysctl_perf_event_paranoid <= 1) - return 1; -#endif - return 0; -} - -/* - * We show kallsyms information even to normal users if we've enabled - * kernel profiling and are explicitly not paranoid (so kptr_restrict - * is clear, and sysctl_perf_event_paranoid isn't set). - * - * Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to - * block even that). - */ -bool kallsyms_show_value(const struct cred *cred) -{ - switch (kptr_restrict) { - case 0: - if (kallsyms_for_perf()) - return true; - fallthrough; - case 1: - if (security_capable(cred, &init_user_ns, CAP_SYSLOG, - CAP_OPT_NOAUDIT) == 0) - return true; - fallthrough; - default: - return false; - } -} - static int kallsyms_open(struct inode *inode, struct file *file) { /* diff --git a/kernel/knosyms.c b/kernel/knosyms.c new file mode 100644 index 000000000000..f2c8755e22e7 --- /dev/null +++ b/kernel/knosyms.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 Samsung Electronics Co., Ltd + * + * Author: + * Maninder singh <maninder1.s@xxxxxxxxxxx> + * Onkarnath <onkarnath.1@xxxxxxxxxxx> + * + * A split of kernel/kallsyms.c + * to contain few generic function definations independent of config KALLSYMS + * or defined under KALLSYMS disabled. + */ + +#include <linux/kallsyms.h> +#include <linux/security.h> + +static inline int kallsyms_for_perf(void) +{ +#ifdef CONFIG_PERF_EVENTS + extern int sysctl_perf_event_paranoid; + + if (sysctl_perf_event_paranoid <= 1) + return 1; +#endif + return 0; +} + +/* + * We show kallsyms information even to normal users if we've enabled + * kernel profiling and are explicitly not paranoid (so kptr_restrict + * is clear, and sysctl_perf_event_paranoid isn't set). + * + * Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to + * block even that). + */ +bool kallsyms_show_value(const struct cred *cred) +{ + switch (kptr_restrict) { + case 0: + if (kallsyms_for_perf()) + return true; + fallthrough; + case 1: + if (security_capable(cred, &init_user_ns, CAP_SYSLOG, + CAP_OPT_NOAUDIT) == 0) + return true; + fallthrough; + default: + return false; + } +} + -- 2.17.1