Skip to content

Commit

Permalink
Merge tag 'modules-5.19-rc7' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/mcgrof/linux

Pull module fixes from Luis Chamberlain:
 "Although most of the move of code in in v5.19-rc1 should have not
  introduced a regression patch review on one of the file changes
  captured a checkpatch warning which advised to use strscpy() and it
  caused a buffer overflow when an incorrect length is passed.

  Another change which checkpatch complained about was an odd RCU usage,
  but that was properly addressed in a separate patch to the move by
  Aaron. That caused a regression with PREEMPT_RT=y due to an unbounded
  latency.

  This series fixes both and adjusts documentation which we forgot to do
  for the move"

* tag 'modules-5.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux:
  module: kallsyms: Ensure preemption in add_kallsyms() with PREEMPT_RT
  doc: module: update file references
  module: Fix "warning: variable 'exit' set but not used"
  module: Fix selfAssignment cppcheck warning
  modules: Fix corruption of /proc/kallsyms
  • Loading branch information
torvalds committed Jul 11, 2022
2 parents 816e51d + e69a661 commit b537439
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Documentation/core-api/kernel-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ Module Loading
Inter Module support
--------------------

Refer to the file kernel/module.c for more information.
Refer to the files in kernel/module/ for more information.

Hardware Interfaces
===================
Expand Down
4 changes: 2 additions & 2 deletions Documentation/core-api/symbol-namespaces.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ namespace ``USB_STORAGE``, use::
The corresponding ksymtab entry struct ``kernel_symbol`` will have the member
``namespace`` set accordingly. A symbol that is exported without a namespace will
refer to ``NULL``. There is no default namespace if none is defined. ``modpost``
and kernel/module.c make use the namespace at build time or module load time,
respectively.
and kernel/module/main.c make use the namespace at build time or module load
time, respectively.

2.2 Using the DEFAULT_SYMBOL_NAMESPACE define
=============================================
Expand Down
10 changes: 5 additions & 5 deletions Documentation/livepatch/module-elf-format.rst
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,11 @@ module->symtab.
=====================================
Normally, a stripped down copy of a module's symbol table (containing only
"core" symbols) is made available through module->symtab (See layout_symtab()
in kernel/module.c). For livepatch modules, the symbol table copied into memory
on module load must be exactly the same as the symbol table produced when the
patch module was compiled. This is because the relocations in each livepatch
relocation section refer to their respective symbols with their symbol indices,
and the original symbol indices (and thus the symtab ordering) must be
in kernel/module/kallsyms.c). For livepatch modules, the symbol table copied
into memory on module load must be exactly the same as the symbol table produced
when the patch module was compiled. This is because the relocations in each
livepatch relocation section refer to their respective symbols with their symbol
indices, and the original symbol indices (and thus the symtab ordering) must be
preserved in order for apply_relocate_add() to find the right symbol.

For example, take this particular rela from a livepatch module:::
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ Di conseguenza, nella tabella dei simboli del kernel ci sarà una voce
rappresentata dalla struttura ``kernel_symbol`` che avrà il campo
``namespace`` (spazio dei nomi) impostato. Un simbolo esportato senza uno spazio
dei nomi avrà questo campo impostato a ``NULL``. Non esiste uno spazio dei nomi
di base. Il programma ``modpost`` e il codice in kernel/module.c usano lo spazio
dei nomi, rispettivamente, durante la compilazione e durante il caricamento
di un modulo.
di base. Il programma ``modpost`` e il codice in kernel/module/main.c usano lo
spazio dei nomi, rispettivamente, durante la compilazione e durante il
caricamento di un modulo.

2.2 Usare il simbolo di preprocessore DEFAULT_SYMBOL_NAMESPACE
==============================================================
Expand Down
2 changes: 1 addition & 1 deletion Documentation/translations/zh_CN/core-api/kernel-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ kernel/kmod.c
模块接口支持
------------

更多信息请参考文件kernel/module.c
更多信息请参阅kernel/module/目录下的文件

硬件接口
========
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@

相应的 ksymtab 条目结构体 ``kernel_symbol`` 将有相应的成员 ``命名空间`` 集。
导出时未指明命名空间的符号将指向 ``NULL`` 。如果没有定义命名空间,则默认没有。
``modpost`` 和kernel/module.c分别在构建时或模块加载时使用名称空间。
``modpost`` 和kernel/module/main.c分别在构建时或模块加载时使用名称空间。

2.2 使用DEFAULT_SYMBOL_NAMESPACE定义
====================================
Expand Down
13 changes: 8 additions & 5 deletions kernel/module/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/mutex.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/mm.h>

#ifndef ARCH_SHF_SMALL
#define ARCH_SHF_SMALL 0
Expand All @@ -30,11 +31,13 @@
* to ensure complete separation of code and data, but
* only when CONFIG_STRICT_MODULE_RWX=y
*/
#ifdef CONFIG_STRICT_MODULE_RWX
# define strict_align(X) PAGE_ALIGN(X)
#else
# define strict_align(X) (X)
#endif
static inline unsigned int strict_align(unsigned int size)
{
if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
return PAGE_ALIGN(size);
else
return size;
}

extern struct mutex module_mutex;
extern struct list_head modules;
Expand Down
35 changes: 22 additions & 13 deletions kernel/module/kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ void layout_symtab(struct module *mod, struct load_info *info)
info->symoffs = ALIGN(mod->data_layout.size, symsect->sh_addralign ?: 1);
info->stroffs = mod->data_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
mod->data_layout.size += strtab_size;
/* Note add_kallsyms() computes strtab_size as core_typeoffs - stroffs */
info->core_typeoffs = mod->data_layout.size;
mod->data_layout.size += ndst * sizeof(char);
mod->data_layout.size = strict_align(mod->data_layout.size);
Expand Down Expand Up @@ -169,19 +170,20 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
Elf_Sym *dst;
char *s;
Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
unsigned long strtab_size;

/* Set up to point into init section. */
mod->kallsyms = (void __rcu *)mod->init_layout.base +
info->mod_kallsyms_init_off;

preempt_disable();
rcu_read_lock();
/* The following is safe since this pointer cannot change */
rcu_dereference_sched(mod->kallsyms)->symtab = (void *)symsec->sh_addr;
rcu_dereference_sched(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
rcu_dereference(mod->kallsyms)->symtab = (void *)symsec->sh_addr;
rcu_dereference(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
/* Make sure we get permanent strtab: don't use info->strtab. */
rcu_dereference_sched(mod->kallsyms)->strtab =
rcu_dereference(mod->kallsyms)->strtab =
(void *)info->sechdrs[info->index.str].sh_addr;
rcu_dereference_sched(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs;
rcu_dereference(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs;

/*
* Now populate the cut down core kallsyms for after init
Expand All @@ -190,22 +192,29 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
mod->core_kallsyms.symtab = dst = mod->data_layout.base + info->symoffs;
mod->core_kallsyms.strtab = s = mod->data_layout.base + info->stroffs;
mod->core_kallsyms.typetab = mod->data_layout.base + info->core_typeoffs;
src = rcu_dereference_sched(mod->kallsyms)->symtab;
for (ndst = i = 0; i < rcu_dereference_sched(mod->kallsyms)->num_symtab; i++) {
rcu_dereference_sched(mod->kallsyms)->typetab[i] = elf_type(src + i, info);
strtab_size = info->core_typeoffs - info->stroffs;
src = rcu_dereference(mod->kallsyms)->symtab;
for (ndst = i = 0; i < rcu_dereference(mod->kallsyms)->num_symtab; i++) {
rcu_dereference(mod->kallsyms)->typetab[i] = elf_type(src + i, info);
if (i == 0 || is_livepatch_module(mod) ||
is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
info->index.pcpu)) {
ssize_t ret;

mod->core_kallsyms.typetab[ndst] =
rcu_dereference_sched(mod->kallsyms)->typetab[i];
rcu_dereference(mod->kallsyms)->typetab[i];
dst[ndst] = src[i];
dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
s += strscpy(s,
&rcu_dereference_sched(mod->kallsyms)->strtab[src[i].st_name],
KSYM_NAME_LEN) + 1;
ret = strscpy(s,
&rcu_dereference(mod->kallsyms)->strtab[src[i].st_name],
strtab_size);
if (ret < 0)
break;
s += ret + 1;
strtab_size -= ret + 1;
}
}
preempt_enable();
rcu_read_unlock();
mod->core_kallsyms.num_symtab = ndst;
}

Expand Down
9 changes: 5 additions & 4 deletions kernel/module/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2939,24 +2939,25 @@ static void cfi_init(struct module *mod)
{
#ifdef CONFIG_CFI_CLANG
initcall_t *init;
#ifdef CONFIG_MODULE_UNLOAD
exitcall_t *exit;
#endif

rcu_read_lock_sched();
mod->cfi_check = (cfi_check_fn)
find_kallsyms_symbol_value(mod, "__cfi_check");
init = (initcall_t *)
find_kallsyms_symbol_value(mod, "__cfi_jt_init_module");
exit = (exitcall_t *)
find_kallsyms_symbol_value(mod, "__cfi_jt_cleanup_module");
rcu_read_unlock_sched();

/* Fix init/exit functions to point to the CFI jump table */
if (init)
mod->init = *init;
#ifdef CONFIG_MODULE_UNLOAD
exit = (exitcall_t *)
find_kallsyms_symbol_value(mod, "__cfi_jt_cleanup_module");
if (exit)
mod->exit = *exit;
#endif
rcu_read_unlock_sched();

cfi_module_add(mod, mod_tree.addr_min);
#endif
Expand Down

0 comments on commit b537439

Please sign in to comment.