Skip to content

Commit

Permalink
Merge tag 'v6.5-rc1-modules-next' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/mcgrof/linux

Pull module updates from Luis Chamberlain:
 "The changes queued up for modules are pretty tame, mostly code removal
  of moving of code.

  Only two minor functional changes are made, the only one which stands
  out is Sebastian Andrzej Siewior's simplification of module reference
  counting by removing preempt_disable() and that has been tested on
  linux-next for well over a month without no regressions.

  I'm now, I guess, also a kitchen sink for some kallsyms changes"

[ There was a mis-communication about the concurrent module load changes
  that I had expected to come through Luis despite me authoring the
  patch. So some of the module updates were left hanging in the email
  ether, and I just committed them separately.

  It's my bad - I should have made it more clear that I expected my
  own patches to come through the module tree too. Now they missed
  linux-next, but hopefully that won't cause any issues    - Linus ]

* tag 'v6.5-rc1-modules-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux:
  kallsyms: make kallsyms_show_value() as generic function
  kallsyms: move kallsyms_show_value() out of kallsyms.c
  kallsyms: remove unsed API lookup_symbol_attrs
  kallsyms: remove unused arch_get_kallsym() helper
  module: Remove preempt_disable() from module reference counting.
  • Loading branch information
Linus Torvalds committed Jun 28, 2023
2 parents 9b9879f + 0eeaf1e commit 4e3c09e
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 152 deletions.
17 changes: 3 additions & 14 deletions include/linux/kallsyms.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ static inline void *dereference_symbol_descriptor(void *ptr)
return ptr;
}

/* How and when do we show kallsyms values? */
extern bool kallsyms_show_value(const struct cred *cred);

#ifdef CONFIG_KALLSYMS
unsigned long kallsyms_sym_address(int idx);
int kallsyms_on_each_symbol(int (*fn)(void *, const char *, unsigned long),
Expand Down Expand Up @@ -93,10 +96,6 @@ extern int sprint_backtrace(char *buffer, unsigned long address);
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 */

Expand Down Expand Up @@ -155,16 +154,6 @@ static inline int lookup_symbol_name(unsigned long addr, char *symname)
return -ERANGE;
}

static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name)
{
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)
{
Expand Down
9 changes: 0 additions & 9 deletions include/linux/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -968,15 +968,6 @@ static inline int lookup_module_symbol_name(unsigned long addr, char *symname)
return -ERANGE;
}

static inline int lookup_module_symbol_attrs(unsigned long addr,
unsigned long *size,
unsigned long *offset,
char *modname,
char *name)
{
return -ERANGE;
}

static inline int module_get_kallsym(unsigned int symnum, unsigned long *value,
char *type, char *name,
char *module_name, int *exported)
Expand Down
2 changes: 1 addition & 1 deletion kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 ksyms_common.o

obj-$(CONFIG_USERMODE_DRIVER) += usermode_driver.o
obj-$(CONFIG_MULTIUSER) += groups.o
Expand Down
91 changes: 1 addition & 90 deletions kernel/kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,34 +484,6 @@ int lookup_symbol_name(unsigned long addr, char *symname)
return 0;
}

int lookup_symbol_attrs(unsigned long addr, unsigned long *size,
unsigned long *offset, char *modname, char *name)
{
int res;

name[0] = '\0';
name[KSYM_NAME_LEN - 1] = '\0';

if (is_ksym_addr(addr)) {
unsigned long pos;

pos = get_symbol_pos(addr, size, offset);
/* Grab name */
kallsyms_expand_symbol(get_symbol_offset(pos),
name, KSYM_NAME_LEN);
modname[0] = '\0';
goto found;
}
/* See if it's in a module. */
res = lookup_module_symbol_attrs(addr, size, offset, modname, name);
if (res)
return res;

found:
cleanup_symbol_name(name);
return 0;
}

/* Look up a kernel symbol and return it in a text buffer. */
static int __sprint_symbol(char *buffer, unsigned long address,
int symbol_offset, int add_offset, int add_buildid)
Expand Down Expand Up @@ -646,7 +618,6 @@ int sprint_backtrace_build_id(char *buffer, unsigned long address)
/* To avoid using get_symbol_offset for every symbol, we carry prefix along. */
struct kallsym_iter {
loff_t pos;
loff_t pos_arch_end;
loff_t pos_mod_end;
loff_t pos_ftrace_mod_end;
loff_t pos_bpf_end;
Expand All @@ -659,29 +630,9 @@ struct kallsym_iter {
int show_value;
};

int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
char *type, char *name)
{
return -EINVAL;
}

static int get_ksymbol_arch(struct kallsym_iter *iter)
{
int ret = arch_get_kallsym(iter->pos - kallsyms_num_syms,
&iter->value, &iter->type,
iter->name);

if (ret < 0) {
iter->pos_arch_end = iter->pos;
return 0;
}

return 1;
}

static int get_ksymbol_mod(struct kallsym_iter *iter)
{
int ret = module_get_kallsym(iter->pos - iter->pos_arch_end,
int ret = module_get_kallsym(iter->pos - kallsyms_num_syms,
&iter->value, &iter->type,
iter->name, iter->module_name,
&iter->exported);
Expand Down Expand Up @@ -764,7 +715,6 @@ static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
iter->nameoff = get_symbol_offset(new_pos);
iter->pos = new_pos;
if (new_pos == 0) {
iter->pos_arch_end = 0;
iter->pos_mod_end = 0;
iter->pos_ftrace_mod_end = 0;
iter->pos_bpf_end = 0;
Expand All @@ -780,10 +730,6 @@ static int update_iter_mod(struct kallsym_iter *iter, loff_t pos)
{
iter->pos = pos;

if ((!iter->pos_arch_end || iter->pos_arch_end > pos) &&
get_ksymbol_arch(iter))
return 1;

if ((!iter->pos_mod_end || iter->pos_mod_end > pos) &&
get_ksymbol_mod(iter))
return 1;
Expand Down Expand Up @@ -961,41 +907,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)
{
/*
Expand Down
43 changes: 43 additions & 0 deletions kernel/ksyms_common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* ksyms_common.c: A split of kernel/kallsyms.c
* Contains a few generic function definations independent of config KALLSYMS.
*/
#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;
}
}
28 changes: 0 additions & 28 deletions kernel/module/kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,34 +381,6 @@ int lookup_module_symbol_name(unsigned long addr, char *symname)
return -ERANGE;
}

int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
unsigned long *offset, char *modname, char *name)
{
struct module *mod;

preempt_disable();
list_for_each_entry_rcu(mod, &modules, list) {
if (mod->state == MODULE_STATE_UNFORMED)
continue;
if (within_module(addr, mod)) {
const char *sym;

sym = find_kallsyms_symbol(mod, addr, size, offset);
if (!sym)
goto out;
if (modname)
strscpy(modname, mod->name, MODULE_NAME_LEN);
if (name)
strscpy(name, sym, KSYM_NAME_LEN);
preempt_enable();
return 0;
}
}
out:
preempt_enable();
return -ERANGE;
}

int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
char *name, char *module_name, int *exported)
{
Expand Down
7 changes: 0 additions & 7 deletions kernel/module/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,10 +820,8 @@ static struct module_attribute modinfo_refcnt =
void __module_get(struct module *module)
{
if (module) {
preempt_disable();
atomic_inc(&module->refcnt);
trace_module_get(module, _RET_IP_);
preempt_enable();
}
}
EXPORT_SYMBOL(__module_get);
Expand All @@ -833,15 +831,12 @@ bool try_module_get(struct module *module)
bool ret = true;

if (module) {
preempt_disable();
/* Note: here, we can fail to get a reference */
if (likely(module_is_live(module) &&
atomic_inc_not_zero(&module->refcnt) != 0))
trace_module_get(module, _RET_IP_);
else
ret = false;

preempt_enable();
}
return ret;
}
Expand All @@ -852,11 +847,9 @@ void module_put(struct module *module)
int ret;

if (module) {
preempt_disable();
ret = atomic_dec_if_positive(&module->refcnt);
WARN_ON(ret < 0); /* Failed to put refcount */
trace_module_put(module, _RET_IP_);
preempt_enable();
}
}
EXPORT_SYMBOL(module_put);
Expand Down
4 changes: 1 addition & 3 deletions tools/testing/selftests/bpf/progs/bpf_iter_ksym.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ int dump_ksym(struct bpf_iter__ksym *ctx)
} else {
BPF_SEQ_PRINTF(seq, "0x%llx %c %s ", value, type, iter->name);
}
if (!iter->pos_arch_end || iter->pos_arch_end > iter->pos)
BPF_SEQ_PRINTF(seq, "CORE ");
else if (!iter->pos_mod_end || iter->pos_mod_end > iter->pos)
if (!iter->pos_mod_end || iter->pos_mod_end > iter->pos)
BPF_SEQ_PRINTF(seq, "MOD ");
else if (!iter->pos_ftrace_mod_end || iter->pos_ftrace_mod_end > iter->pos)
BPF_SEQ_PRINTF(seq, "FTRACE_MOD ");
Expand Down

0 comments on commit 4e3c09e

Please sign in to comment.