Skip to content

Commit c8be542

Browse files
committed
Merge tag 'modules-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux
Pull module updates from Petr Pavlu: - Make .static_call_sites in modules read-only after init The .static_call_sites sections in modules have been made read-only after init to avoid any (non-)accidental modifications, similarly to how they are read-only after init in vmlinux - The rest are minor cleanups * tag 'modules-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux: module: Remove outdated comment about text_size module: Make .static_call_sites read-only after init module: Add a separate function to mark sections as read-only after init module: Constify parameters of module_enforce_rwx_sections()
2 parents fd1f847 + a0b018a commit c8be542

File tree

3 files changed

+57
-24
lines changed

3 files changed

+57
-24
lines changed

kernel/module/internal.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,11 @@ int module_enable_rodata_ro(const struct module *mod);
322322
int module_enable_rodata_ro_after_init(const struct module *mod);
323323
int module_enable_data_nx(const struct module *mod);
324324
int module_enable_text_rox(const struct module *mod);
325-
int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
326-
char *secstrings, struct module *mod);
325+
int module_enforce_rwx_sections(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
326+
const char *secstrings,
327+
const struct module *mod);
328+
void module_mark_ro_after_init(const Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
329+
const char *secstrings);
327330

328331
#ifdef CONFIG_MODULE_SIG
329332
int module_sig_check(struct load_info *info, int flags);

kernel/module/main.c

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,12 +1562,11 @@ static void __layout_sections(struct module *mod, struct load_info *info, bool i
15621562
{
15631563
unsigned int m, i;
15641564

1565+
/*
1566+
* { Mask of required section header flags,
1567+
* Mask of excluded section header flags }
1568+
*/
15651569
static const unsigned long masks[][2] = {
1566-
/*
1567-
* NOTE: all executable code must be the first section
1568-
* in this array; otherwise modify the text_size
1569-
* finder in the two loops below
1570-
*/
15711570
{ SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL },
15721571
{ SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL },
15731572
{ SHF_RO_AFTER_INIT | SHF_ALLOC, ARCH_SHF_SMALL },
@@ -2768,7 +2767,6 @@ core_param(module_blacklist, module_blacklist, charp, 0400);
27682767
static struct module *layout_and_allocate(struct load_info *info, int flags)
27692768
{
27702769
struct module *mod;
2771-
unsigned int ndx;
27722770
int err;
27732771

27742772
/* Allow arches to frob section contents and sizes. */
@@ -2786,22 +2784,11 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
27862784
info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC;
27872785

27882786
/*
2789-
* Mark ro_after_init section with SHF_RO_AFTER_INIT so that
2790-
* layout_sections() can put it in the right place.
2787+
* Mark relevant sections as SHF_RO_AFTER_INIT so layout_sections() can
2788+
* put them in the right place.
27912789
* Note: ro_after_init sections also have SHF_{WRITE,ALLOC} set.
27922790
*/
2793-
ndx = find_sec(info, ".data..ro_after_init");
2794-
if (ndx)
2795-
info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT;
2796-
/*
2797-
* Mark the __jump_table section as ro_after_init as well: these data
2798-
* structures are never modified, with the exception of entries that
2799-
* refer to code in the __init section, which are annotated as such
2800-
* at module load time.
2801-
*/
2802-
ndx = find_sec(info, "__jump_table");
2803-
if (ndx)
2804-
info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT;
2791+
module_mark_ro_after_init(info->hdr, info->sechdrs, info->secstrings);
28052792

28062793
/*
28072794
* Determine total sizes, and put offsets in sh_entsize. For now

kernel/module/strict_rwx.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,9 @@ int module_enable_data_nx(const struct module *mod)
8787
return 0;
8888
}
8989

90-
int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
91-
char *secstrings, struct module *mod)
90+
int module_enforce_rwx_sections(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
91+
const char *secstrings,
92+
const struct module *mod)
9293
{
9394
const unsigned long shf_wx = SHF_WRITE | SHF_EXECINSTR;
9495
int i;
@@ -106,3 +107,45 @@ int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
106107

107108
return 0;
108109
}
110+
111+
static const char *const ro_after_init[] = {
112+
/*
113+
* Section .data..ro_after_init holds data explicitly annotated by
114+
* __ro_after_init.
115+
*/
116+
".data..ro_after_init",
117+
118+
/*
119+
* Section __jump_table holds data structures that are never modified,
120+
* with the exception of entries that refer to code in the __init
121+
* section, which are marked as such at module load time.
122+
*/
123+
"__jump_table",
124+
125+
#ifdef CONFIG_HAVE_STATIC_CALL_INLINE
126+
/*
127+
* Section .static_call_sites holds data structures that need to be
128+
* sorted and processed at module load time but are never modified
129+
* afterwards.
130+
*/
131+
".static_call_sites",
132+
#endif
133+
};
134+
135+
void module_mark_ro_after_init(const Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
136+
const char *secstrings)
137+
{
138+
int i, j;
139+
140+
for (i = 1; i < hdr->e_shnum; i++) {
141+
Elf_Shdr *shdr = &sechdrs[i];
142+
143+
for (j = 0; j < ARRAY_SIZE(ro_after_init); j++) {
144+
if (strcmp(secstrings + shdr->sh_name,
145+
ro_after_init[j]) == 0) {
146+
shdr->sh_flags |= SHF_RO_AFTER_INIT;
147+
break;
148+
}
149+
}
150+
}
151+
}

0 commit comments

Comments
 (0)