| @@ -1221,18 +1221,6 @@ void __weak module_arch_freeing_init(struct module *mod) · 1220 unmodified lines |
| 1221 | 1221 | { |
| 1222 | 1222 | } |
| 1223 | 1223 | |
| 1224 | | −void *__module_writable_address(struct module *mod, void *loc) |
| 1225 | | −{ |
| 1226 | | − for_class_mod_mem_type(type, text) { |
| 1227 | | − struct module_memory *mem = &mod->mem[type]; |
| 1228 | | − |
| 1229 | | − if (loc >= mem->base && loc < mem->base + mem->size) |
| 1230 | | − return loc + (mem->rw_copy - mem->base); |
| 1231 | | − } |
| 1232 | | − |
| 1233 | | − return loc; |
| 1234 | | −} |
| 1235 | | − |
| 1236 | 1224 | static int module_memory_alloc(struct module *mod, enum mod_mem_type type) |
| 1237 | 1225 | { |
| 1238 | 1226 | unsigned int size = PAGE_ALIGN(mod->mem[type].size); |
| @@ -1250,21 +1238,15 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type) · 11 unmodified lines |
| 1250 | 1238 | if (!ptr) |
| 1251 | 1239 | return -ENOMEM; |
| 1252 | 1240 | |
| 1253 | | − mod->mem[type].base = ptr; |
| 1254 | | − |
| 1255 | 1241 | if (execmem_is_rox(execmem_type)) { |
| 1256 | | − ptr = vzalloc(size); |
| 1242 | + int err = execmem_make_temp_rw(ptr, size); |
| 1257 | 1243 | |
| 1258 | | − if (!ptr) { |
| 1259 | | − execmem_free(mod->mem[type].base); |
| 1244 | + if (err) { |
| 1245 | + execmem_free(ptr); |
| 1260 | 1246 | return -ENOMEM; |
| 1261 | 1247 | } |
| 1262 | 1248 | |
| 1263 | | − mod->mem[type].rw_copy = ptr; |
| 1264 | 1249 | mod->mem[type].is_rox = true; |
| 1265 | | − } else { |
| 1266 | | − mod->mem[type].rw_copy = mod->mem[type].base; |
| 1267 | | − memset(mod->mem[type].base, 0, size); |
| 1268 | 1250 | } |
| 1269 | 1251 | |
| 1270 | 1252 | /* |
| @@ -1280,16 +1262,26 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type) · 9 unmodified lines |
| 1280 | 1262 | */ |
| 1281 | 1263 | kmemleak_not_leak(ptr); |
| 1282 | 1264 | |
| 1265 | + memset(ptr, 0, size); |
| 1266 | + mod->mem[type].base = ptr; |
| 1267 | + |
| 1283 | 1268 | return 0; |
| 1284 | 1269 | } |
| 1285 | 1270 | |
| 1271 | +static void module_memory_restore_rox(struct module *mod) |
| 1272 | +{ |
| 1273 | + for_class_mod_mem_type(type, text) { |
| 1274 | + struct module_memory *mem = &mod->mem[type]; |
| 1275 | + |
| 1276 | + if (mem->is_rox) |
| 1277 | + execmem_restore_rox(mem->base, mem->size); |
| 1278 | + } |
| 1279 | +} |
| 1280 | + |
| 1286 | 1281 | static void module_memory_free(struct module *mod, enum mod_mem_type type) |
| 1287 | 1282 | { |
| 1288 | 1283 | struct module_memory *mem = &mod->mem[type]; |
| 1289 | 1284 | |
| 1290 | | − if (mem->is_rox) |
| 1291 | | − vfree(mem->rw_copy); |
| 1292 | | − |
| 1293 | 1285 | execmem_free(mem->base); |
| 1294 | 1286 | } |
| 1295 | 1287 | |
| @@ -2642,7 +2634,6 @@ static int move_module(struct module *mod, struct load_info *info) · 1346 unmodified lines |
| 2642 | 2634 | for_each_mod_mem_type(type) { |
| 2643 | 2635 | if (!mod->mem[type].size) { |
| 2644 | 2636 | mod->mem[type].base = NULL; |
| 2645 | | − mod->mem[type].rw_copy = NULL; |
| 2646 | 2637 | continue; |
| 2647 | 2638 | } |
| 2648 | 2639 | |
| @@ -2659,7 +2650,6 @@ static int move_module(struct module *mod, struct load_info *info) · 10 unmodified lines |
| 2659 | 2650 | void *dest; |
| 2660 | 2651 | Elf_Shdr *shdr = &info->sechdrs[i]; |
| 2661 | 2652 | const char *sname; |
| 2662 | | − unsigned long addr; |
| 2663 | 2653 | |
| 2664 | 2654 | if (!(shdr->sh_flags & SHF_ALLOC)) |
| 2665 | 2655 | continue; |
| @@ -2680,14 +2670,12 @@ static int move_module(struct module *mod, struct load_info *info) · 14 unmodified lines |
| 2680 | 2670 | ret = PTR_ERR(dest); |
| 2681 | 2671 | goto out_err; |
| 2682 | 2672 | } |
| 2683 | | − addr = (unsigned long)dest; |
| 2684 | 2673 | codetag_section_found = true; |
| 2685 | 2674 | } else { |
| 2686 | 2675 | enum mod_mem_type type = shdr->sh_entsize >> SH_ENTSIZE_TYPE_SHIFT; |
| 2687 | 2676 | unsigned long offset = shdr->sh_entsize & SH_ENTSIZE_OFFSET_MASK; |
| 2688 | 2677 | |
| 2689 | | − addr = (unsigned long)mod->mem[type].base + offset; |
| 2690 | | − dest = mod->mem[type].rw_copy + offset; |
| 2678 | + dest = mod->mem[type].base + offset; |
| 2691 | 2679 | } |
| 2692 | 2680 | |
| 2693 | 2681 | if (shdr->sh_type != SHT_NOBITS) { |
| @@ -2710,13 +2698,14 @@ static int move_module(struct module *mod, struct load_info *info) · 16 unmodified lines |
| 2710 | 2698 | * users of info can keep taking advantage and using the newly |
| 2711 | 2699 | * minted official memory area. |
| 2712 | 2700 | */ |
| 2713 | | − shdr->sh_addr = addr; |
| 2701 | + shdr->sh_addr = (unsigned long)dest; |
| 2714 | 2702 | pr_debug("\t0x%lx 0x%.8lx %s\n", (long)shdr->sh_addr, |
| 2715 | 2703 | (long)shdr->sh_size, info->secstrings + shdr->sh_name); |
| 2716 | 2704 | } |
| 2717 | 2705 | |
| 2718 | 2706 | return 0; |
| 2719 | 2707 | out_err: |
| 2708 | + module_memory_restore_rox(mod); |
| 2720 | 2709 | for (t--; t >= 0; t--) |
| 2721 | 2710 | module_memory_free(mod, t); |
| 2722 | 2711 | if (codetag_section_found) |
| @@ -2863,17 +2852,8 @@ int __weak module_finalize(const Elf_Ehdr *hdr, · 140 unmodified lines |
| 2863 | 2852 | return 0; |
| 2864 | 2853 | } |
| 2865 | 2854 | |
| 2866 | | −int __weak module_post_finalize(const Elf_Ehdr *hdr, |
| 2867 | | − const Elf_Shdr *sechdrs, |
| 2868 | | − struct module *me) |
| 2869 | | −{ |
| 2870 | | − return 0; |
| 2871 | | −} |
| 2872 | | − |
| 2873 | 2855 | static int post_relocation(struct module *mod, const struct load_info *info) |
| 2874 | 2856 | { |
| 2875 | | − int ret; |
| 2876 | | − |
| 2877 | 2857 | /* Sort exception table now relocations are done. */ |
| 2878 | 2858 | sort_extable(mod->extable, mod->extable + mod->num_exentries); |
| 2879 | 2859 | |
| @@ -2885,24 +2865,7 @@ static int post_relocation(struct module *mod, const struct load_info *info) · 5 unmodified lines |
| 2885 | 2865 | add_kallsyms(mod, info); |
| 2886 | 2866 | |
| 2887 | 2867 | /* Arch-specific module finalizing. */ |
| 2888 | | − ret = module_finalize(info->hdr, info->sechdrs, mod); |
| 2889 | | − if (ret) |
| 2890 | | − return ret; |
| 2891 | | − |
| 2892 | | − for_each_mod_mem_type(type) { |
| 2893 | | − struct module_memory *mem = &mod->mem[type]; |
| 2894 | | − |
| 2895 | | − if (mem->is_rox) { |
| 2896 | | − if (!execmem_update_copy(mem->base, mem->rw_copy, |
| 2897 | | − mem->size)) |
| 2898 | | − return -ENOMEM; |
| 2899 | | − |
| 2900 | | − vfree(mem->rw_copy); |
| 2901 | | − mem->rw_copy = NULL; |
| 2902 | | − } |
| 2903 | | − } |
| 2904 | | − |
| 2905 | | − return module_post_finalize(info->hdr, info->sechdrs, mod); |
| 2868 | + return module_finalize(info->hdr, info->sechdrs, mod); |
| 2906 | 2869 | } |
| 2907 | 2870 | |
| 2908 | 2871 | /* Call module constructors. */ |
| @@ -3499,6 +3462,7 @@ static int load_module(struct load_info *info, const char __user *uargs, · 590 unmodified lines |
| 3499 | 3462 | mod->mem[type].size); |
| 3500 | 3463 | } |
| 3501 | 3464 | |
| 3465 | + module_memory_restore_rox(mod); |
| 3502 | 3466 | module_deallocate(mod, info); |
| 3503 | 3467 | free_copy: |
| 3504 | 3468 | /* |