Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions kernel/module/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,11 @@ int module_enable_rodata_ro(const struct module *mod);
int module_enable_rodata_ro_after_init(const struct module *mod);
int module_enable_data_nx(const struct module *mod);
int module_enable_text_rox(const struct module *mod);
int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
char *secstrings, struct module *mod);
int module_enforce_rwx_sections(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
const char *secstrings,
const struct module *mod);
void module_mark_ro_after_init(const Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
const char *secstrings);

#ifdef CONFIG_MODULE_SIG
int module_sig_check(struct load_info *info, int flags);
Expand Down
18 changes: 3 additions & 15 deletions kernel/module/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2768,7 +2768,6 @@ core_param(module_blacklist, module_blacklist, charp, 0400);
static struct module *layout_and_allocate(struct load_info *info, int flags)
{
struct module *mod;
unsigned int ndx;
int err;

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

/*
* Mark ro_after_init section with SHF_RO_AFTER_INIT so that
* layout_sections() can put it in the right place.
* Mark relevant sections as SHF_RO_AFTER_INIT so layout_sections() can
* put them in the right place.
* Note: ro_after_init sections also have SHF_{WRITE,ALLOC} set.
*/
ndx = find_sec(info, ".data..ro_after_init");
if (ndx)
info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT;
/*
* Mark the __jump_table section as ro_after_init as well: these data
* structures are never modified, with the exception of entries that
* refer to code in the __init section, which are annotated as such
* at module load time.
*/
ndx = find_sec(info, "__jump_table");
if (ndx)
info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT;
module_mark_ro_after_init(info->hdr, info->sechdrs, info->secstrings);

/*
* Determine total sizes, and put offsets in sh_entsize. For now
Expand Down
47 changes: 45 additions & 2 deletions kernel/module/strict_rwx.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ int module_enable_data_nx(const struct module *mod)
return 0;
}

int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
char *secstrings, struct module *mod)
int module_enforce_rwx_sections(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
const char *secstrings,
const struct module *mod)
{
const unsigned long shf_wx = SHF_WRITE | SHF_EXECINSTR;
int i;
Expand All @@ -106,3 +107,45 @@ int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,

return 0;
}

static const char *const ro_after_init[] = {
/*
* Section .data..ro_after_init holds data explicitly annotated by
* __ro_after_init.
*/
".data..ro_after_init",

/*
* Section __jump_table holds data structures that are never modified,
* with the exception of entries that refer to code in the __init
* section, which are marked as such at module load time.
*/
"__jump_table",

#ifdef CONFIG_HAVE_STATIC_CALL_INLINE
/*
* Section .static_call_sites holds data structures that need to be
* sorted and processed at module load time but are never modified
* afterwards.
*/
".static_call_sites",
#endif
};

void module_mark_ro_after_init(const Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
const char *secstrings)
{
int i, j;

for (i = 1; i < hdr->e_shnum; i++) {
Elf_Shdr *shdr = &sechdrs[i];

for (j = 0; j < ARRAY_SIZE(ro_after_init); j++) {
if (strcmp(secstrings + shdr->sh_name,
ro_after_init[j]) == 0) {
shdr->sh_flags |= SHF_RO_AFTER_INIT;
break;
}
}
}
}
Loading