0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/mm.h>
0010 #include <linux/vmalloc.h>
0011 #include <linux/set_memory.h>
0012 #include "internal.h"
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 static void frob_text(const struct module_layout *layout,
0036 int (*set_memory)(unsigned long start, int num_pages))
0037 {
0038 set_memory((unsigned long)layout->base,
0039 PAGE_ALIGN(layout->text_size) >> PAGE_SHIFT);
0040 }
0041
0042 static void frob_rodata(const struct module_layout *layout,
0043 int (*set_memory)(unsigned long start, int num_pages))
0044 {
0045 set_memory((unsigned long)layout->base + layout->text_size,
0046 (layout->ro_size - layout->text_size) >> PAGE_SHIFT);
0047 }
0048
0049 static void frob_ro_after_init(const struct module_layout *layout,
0050 int (*set_memory)(unsigned long start, int num_pages))
0051 {
0052 set_memory((unsigned long)layout->base + layout->ro_size,
0053 (layout->ro_after_init_size - layout->ro_size) >> PAGE_SHIFT);
0054 }
0055
0056 static void frob_writable_data(const struct module_layout *layout,
0057 int (*set_memory)(unsigned long start, int num_pages))
0058 {
0059 set_memory((unsigned long)layout->base + layout->ro_after_init_size,
0060 (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT);
0061 }
0062
0063 static bool layout_check_misalignment(const struct module_layout *layout)
0064 {
0065 return WARN_ON(!PAGE_ALIGNED(layout->base)) ||
0066 WARN_ON(!PAGE_ALIGNED(layout->text_size)) ||
0067 WARN_ON(!PAGE_ALIGNED(layout->ro_size)) ||
0068 WARN_ON(!PAGE_ALIGNED(layout->ro_after_init_size)) ||
0069 WARN_ON(!PAGE_ALIGNED(layout->size));
0070 }
0071
0072 bool module_check_misalignment(const struct module *mod)
0073 {
0074 if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
0075 return false;
0076
0077 return layout_check_misalignment(&mod->core_layout) ||
0078 layout_check_misalignment(&mod->data_layout) ||
0079 layout_check_misalignment(&mod->init_layout);
0080 }
0081
0082 void module_enable_x(const struct module *mod)
0083 {
0084 if (!PAGE_ALIGNED(mod->core_layout.base) ||
0085 !PAGE_ALIGNED(mod->init_layout.base))
0086 return;
0087
0088 frob_text(&mod->core_layout, set_memory_x);
0089 frob_text(&mod->init_layout, set_memory_x);
0090 }
0091
0092 void module_enable_ro(const struct module *mod, bool after_init)
0093 {
0094 if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
0095 return;
0096 #ifdef CONFIG_STRICT_MODULE_RWX
0097 if (!rodata_enabled)
0098 return;
0099 #endif
0100
0101 set_vm_flush_reset_perms(mod->core_layout.base);
0102 set_vm_flush_reset_perms(mod->init_layout.base);
0103 frob_text(&mod->core_layout, set_memory_ro);
0104
0105 frob_rodata(&mod->data_layout, set_memory_ro);
0106 frob_text(&mod->init_layout, set_memory_ro);
0107 frob_rodata(&mod->init_layout, set_memory_ro);
0108
0109 if (after_init)
0110 frob_ro_after_init(&mod->data_layout, set_memory_ro);
0111 }
0112
0113 void module_enable_nx(const struct module *mod)
0114 {
0115 if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
0116 return;
0117
0118 frob_rodata(&mod->data_layout, set_memory_nx);
0119 frob_ro_after_init(&mod->data_layout, set_memory_nx);
0120 frob_writable_data(&mod->data_layout, set_memory_nx);
0121 frob_rodata(&mod->init_layout, set_memory_nx);
0122 frob_writable_data(&mod->init_layout, set_memory_nx);
0123 }
0124
0125 int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
0126 char *secstrings, struct module *mod)
0127 {
0128 const unsigned long shf_wx = SHF_WRITE | SHF_EXECINSTR;
0129 int i;
0130
0131 if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
0132 return 0;
0133
0134 for (i = 0; i < hdr->e_shnum; i++) {
0135 if ((sechdrs[i].sh_flags & shf_wx) == shf_wx) {
0136 pr_err("%s: section %s (index %d) has invalid WRITE|EXEC flags\n",
0137 mod->name, secstrings + sechdrs[i].sh_name, i);
0138 return -ENOEXEC;
0139 }
0140 }
0141
0142 return 0;
0143 }