| @@ -1857,10 +1857,11 @@ static void mod_sysfs_teardown(struct module *mod) · 1856 unmodified lines |
| 1857 | * from modification and any data from execution. | 1857 | * from modification and any data from execution. |
| 1858 | * | 1858 | * |
| 1859 | * General layout of module is: | 1859 | * General layout of module is: |
| 1860 | * [text] [read-only-data] [writable data] | 1860 | * [text] [read-only-data] [ro-after-init] [writable data] |
| 1861 | * text_size -----^ ^ ^ | 1861 | * text_size -----^ ^ ^ ^ |
| 1862 | * ro_size ------------------------| | | 1862 | * ro_size ------------------------| | | |
| 1863 | * size -------------------------------------------| | 1863 | * ro_after_init_size -----------------------------| | |
| | 1864 | * size -----------------------------------------------------------| |
| 1864 | * | 1865 | * |
| 1865 | * These values are always page-aligned (as is base) | 1866 | * These values are always page-aligned (as is base) |
| 1866 | */ | 1867 | */ |
| @@ -1883,14 +1884,24 @@ static void frob_rodata(const struct module_layout *layout, · 16 unmodified lines |
| 1883 | (layout->ro_size - layout->text_size) >> PAGE_SHIFT); | 1884 | (layout->ro_size - layout->text_size) >> PAGE_SHIFT); |
| 1884 | } | 1885 | } |
| 1885 | | 1886 | |
| | 1887 | static void frob_ro_after_init(const struct module_layout *layout, |
| | 1888 | int (*set_memory)(unsigned long start, int num_pages)) |
| | 1889 | { |
| | 1890 | BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); |
| | 1891 | BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); |
| | 1892 | BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1)); |
| | 1893 | set_memory((unsigned long)layout->base + layout->ro_size, |
| | 1894 | (layout->ro_after_init_size - layout->ro_size) >> PAGE_SHIFT); |
| | 1895 | } |
| | 1896 | |
| 1886 | static void frob_writable_data(const struct module_layout *layout, | 1897 | static void frob_writable_data(const struct module_layout *layout, |
| 1887 | int (*set_memory)(unsigned long start, int num_pages)) | 1898 | int (*set_memory)(unsigned long start, int num_pages)) |
| 1888 | { | 1899 | { |
| 1889 | BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); | 1900 | BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); |
| 1890 | BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); | 1901 | BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1)); |
| 1891 | BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1)); | 1902 | BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1)); |
| 1892 | set_memory((unsigned long)layout->base + layout->ro_size, | 1903 | set_memory((unsigned long)layout->base + layout->ro_after_init_size, |
| 1893 | (layout->size - layout->ro_size) >> PAGE_SHIFT); | 1904 | (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT); |
| 1894 | } | 1905 | } |
| 1895 | | 1906 | |
| 1896 | /* livepatching wants to disable read-only so it can frob module. */ | 1907 | /* livepatching wants to disable read-only so it can frob module. */ |
| @@ -1898,21 +1909,26 @@ void module_disable_ro(const struct module *mod) · 1 unmodified line |
| 1898 | { | 1909 | { |
| 1899 | frob_text(&mod->core_layout, set_memory_rw); | 1910 | frob_text(&mod->core_layout, set_memory_rw); |
| 1900 | frob_rodata(&mod->core_layout, set_memory_rw); | 1911 | frob_rodata(&mod->core_layout, set_memory_rw); |
| | 1912 | frob_ro_after_init(&mod->core_layout, set_memory_rw); |
| 1901 | frob_text(&mod->init_layout, set_memory_rw); | 1913 | frob_text(&mod->init_layout, set_memory_rw); |
| 1902 | frob_rodata(&mod->init_layout, set_memory_rw); | 1914 | frob_rodata(&mod->init_layout, set_memory_rw); |
| 1903 | } | 1915 | } |
| 1904 | | 1916 | |
| 1905 | void module_enable_ro(const struct module *mod) | 1917 | void module_enable_ro(const struct module *mod, bool after_init) |
| 1906 | { | 1918 | { |
| 1907 | frob_text(&mod->core_layout, set_memory_ro); | 1919 | frob_text(&mod->core_layout, set_memory_ro); |
| 1908 | frob_rodata(&mod->core_layout, set_memory_ro); | 1920 | frob_rodata(&mod->core_layout, set_memory_ro); |
| 1909 | frob_text(&mod->init_layout, set_memory_ro); | 1921 | frob_text(&mod->init_layout, set_memory_ro); |
| 1910 | frob_rodata(&mod->init_layout, set_memory_ro); | 1922 | frob_rodata(&mod->init_layout, set_memory_ro); |
| | 1923 | |
| | 1924 | if (after_init) |
| | 1925 | frob_ro_after_init(&mod->core_layout, set_memory_ro); |
| 1911 | } | 1926 | } |
| 1912 | | 1927 | |
| 1913 | static void module_enable_nx(const struct module *mod) | 1928 | static void module_enable_nx(const struct module *mod) |
| 1914 | { | 1929 | { |
| 1915 | frob_rodata(&mod->core_layout, set_memory_nx); | 1930 | frob_rodata(&mod->core_layout, set_memory_nx); |
| | 1931 | frob_ro_after_init(&mod->core_layout, set_memory_nx); |
| 1916 | frob_writable_data(&mod->core_layout, set_memory_nx); | 1932 | frob_writable_data(&mod->core_layout, set_memory_nx); |
| 1917 | frob_rodata(&mod->init_layout, set_memory_nx); | 1933 | frob_rodata(&mod->init_layout, set_memory_nx); |
| 1918 | frob_writable_data(&mod->init_layout, set_memory_nx); | 1934 | frob_writable_data(&mod->init_layout, set_memory_nx); |
| @@ -1921,6 +1937,7 @@ static void module_enable_nx(const struct module *mod) · 2 unmodified lines |
| 1921 | static void module_disable_nx(const struct module *mod) | 1937 | static void module_disable_nx(const struct module *mod) |
| 1922 | { | 1938 | { |
| 1923 | frob_rodata(&mod->core_layout, set_memory_x); | 1939 | frob_rodata(&mod->core_layout, set_memory_x); |
| | 1940 | frob_ro_after_init(&mod->core_layout, set_memory_x); |
| 1924 | frob_writable_data(&mod->core_layout, set_memory_x); | 1941 | frob_writable_data(&mod->core_layout, set_memory_x); |
| 1925 | frob_rodata(&mod->init_layout, set_memory_x); | 1942 | frob_rodata(&mod->init_layout, set_memory_x); |
| 1926 | frob_writable_data(&mod->init_layout, set_memory_x); | 1943 | frob_writable_data(&mod->init_layout, set_memory_x); |
| @@ -1963,6 +1980,8 @@ static void disable_ro_nx(const struct module_layout *layout) · 36 unmodified lines |
| 1963 | frob_text(layout, set_memory_rw); | 1980 | frob_text(layout, set_memory_rw); |
| 1964 | frob_rodata(layout, set_memory_rw); | 1981 | frob_rodata(layout, set_memory_rw); |
| 1965 | frob_rodata(layout, set_memory_x); | 1982 | frob_rodata(layout, set_memory_x); |
| | 1983 | frob_ro_after_init(layout, set_memory_rw); |
| | 1984 | frob_ro_after_init(layout, set_memory_x); |
| 1966 | frob_writable_data(layout, set_memory_x); | 1985 | frob_writable_data(layout, set_memory_x); |
| 1967 | } | 1986 | } |
| 1968 | | 1987 | |
| @@ -2305,6 +2324,7 @@ static void layout_sections(struct module *mod, struct load_info *info) · 336 unmodified lines |
| 2305 | * finder in the two loops below */ | 2324 | * finder in the two loops below */ |
| 2306 | { SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL }, | 2325 | { SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL }, |
| 2307 | { SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL }, | 2326 | { SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL }, |
| | 2327 | { SHF_RO_AFTER_INIT | SHF_ALLOC, ARCH_SHF_SMALL }, |
| 2308 | { SHF_WRITE | SHF_ALLOC, ARCH_SHF_SMALL }, | 2328 | { SHF_WRITE | SHF_ALLOC, ARCH_SHF_SMALL }, |
| 2309 | { ARCH_SHF_SMALL | SHF_ALLOC, 0 } | 2329 | { ARCH_SHF_SMALL | SHF_ALLOC, 0 } |
| 2310 | }; | 2330 | }; |
| @@ -2336,7 +2356,11 @@ static void layout_sections(struct module *mod, struct load_info *info) · 25 unmodified lines |
| 2336 | mod->core_layout.size = debug_align(mod->core_layout.size); | 2356 | mod->core_layout.size = debug_align(mod->core_layout.size); |
| 2337 | mod->core_layout.ro_size = mod->core_layout.size; | 2357 | mod->core_layout.ro_size = mod->core_layout.size; |
| 2338 | break; | 2358 | break; |
| 2339 | case 3: /* whole core */ | 2359 | case 2: /* RO after init */ |
| | 2360 | mod->core_layout.size = debug_align(mod->core_layout.size); |
| | 2361 | mod->core_layout.ro_after_init_size = mod->core_layout.size; |
| | 2362 | break; |
| | 2363 | case 4: /* whole core */ |
| 2340 | mod->core_layout.size = debug_align(mod->core_layout.size); | 2364 | mod->core_layout.size = debug_align(mod->core_layout.size); |
| 2341 | break; | 2365 | break; |
| 2342 | } | 2366 | } |
| @@ -2366,7 +2390,14 @@ static void layout_sections(struct module *mod, struct load_info *info) · 23 unmodified lines |
| 2366 | mod->init_layout.size = debug_align(mod->init_layout.size); | 2390 | mod->init_layout.size = debug_align(mod->init_layout.size); |
| 2367 | mod->init_layout.ro_size = mod->init_layout.size; | 2391 | mod->init_layout.ro_size = mod->init_layout.size; |
| 2368 | break; | 2392 | break; |
| 2369 | case 3: /* whole init */ | 2393 | case 2: |
| | 2394 | /* |
| | 2395 | * RO after init doesn't apply to init_layout (only |
| | 2396 | * core_layout), so it just takes the value of ro_size. |
| | 2397 | */ |
| | 2398 | mod->init_layout.ro_after_init_size = mod->init_layout.ro_size; |
| | 2399 | break; |
| | 2400 | case 4: /* whole init */ |
| 2370 | mod->init_layout.size = debug_align(mod->init_layout.size); | 2401 | mod->init_layout.size = debug_align(mod->init_layout.size); |
| 2371 | break; | 2402 | break; |
| 2372 | } | 2403 | } |
| @@ -3193,6 +3224,7 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) · 820 unmodified lines |
| 3193 | { | 3224 | { |
| 3194 | /* Module within temporary copy. */ | 3225 | /* Module within temporary copy. */ |
| 3195 | struct module *mod; | 3226 | struct module *mod; |
| | 3227 | unsigned int ndx; |
| 3196 | int err; | 3228 | int err; |
| 3197 | | 3229 | |
| 3198 | mod = setup_load_info(info, flags); | 3230 | mod = setup_load_info(info, flags); |
| @@ -3215,6 +3247,15 @@ static struct module *layout_and_allocate(struct load_info *info, int flags) · 16 unmodified lines |
| 3215 | /* We will do a special allocation for per-cpu sections later. */ | 3247 | /* We will do a special allocation for per-cpu sections later. */ |
| 3216 | info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC; | 3248 | info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC; |
| 3217 | | 3249 | |
| | 3250 | /* |
| | 3251 | * Mark ro_after_init section with SHF_RO_AFTER_INIT so that |
| | 3252 | * layout_sections() can put it in the right place. |
| | 3253 | * Note: ro_after_init sections also have SHF_{WRITE,ALLOC} set. |
| | 3254 | */ |
| | 3255 | ndx = find_sec(info, ".data..ro_after_init"); |
| | 3256 | if (ndx) |
| | 3257 | info->sechdrs[ndx].sh_flags |= SHF_RO_AFTER_INIT; |
| | 3258 | |
| 3218 | /* Determine total sizes, and put offsets in sh_entsize. For now | 3259 | /* Determine total sizes, and put offsets in sh_entsize. For now |
| 3219 | this is done generically; there doesn't appear to be any | 3260 | this is done generically; there doesn't appear to be any |
| 3220 | special cases for the architectures. */ | 3261 | special cases for the architectures. */ |
| @@ -3381,12 +3422,14 @@ static noinline int do_init_module(struct module *mod) · 160 unmodified lines |
| 3381 | /* Switch to core kallsyms now init is done: kallsyms may be walking! */ | 3422 | /* Switch to core kallsyms now init is done: kallsyms may be walking! */ |
| 3382 | rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms); | 3423 | rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms); |
| 3383 | #endif | 3424 | #endif |
| | 3425 | module_enable_ro(mod, true); |
| 3384 | mod_tree_remove_init(mod); | 3426 | mod_tree_remove_init(mod); |
| 3385 | disable_ro_nx(&mod->init_layout); | 3427 | disable_ro_nx(&mod->init_layout); |
| 3386 | module_arch_freeing_init(mod); | 3428 | module_arch_freeing_init(mod); |
| 3387 | mod->init_layout.base = NULL; | 3429 | mod->init_layout.base = NULL; |
| 3388 | mod->init_layout.size = 0; | 3430 | mod->init_layout.size = 0; |
| 3389 | mod->init_layout.ro_size = 0; | 3431 | mod->init_layout.ro_size = 0; |
| | 3432 | mod->init_layout.ro_after_init_size = 0; |
| 3390 | mod->init_layout.text_size = 0; | 3433 | mod->init_layout.text_size = 0; |
| 3391 | /* | 3434 | /* |
| 3392 | * We want to free module_init, but be aware that kallsyms may be | 3435 | * We want to free module_init, but be aware that kallsyms may be |
| @@ -3478,8 +3521,7 @@ static int complete_formation(struct module *mod, struct load_info *info) · 85 unmodified lines |
| 3478 | /* This relies on module_mutex for list integrity. */ | 3521 | /* This relies on module_mutex for list integrity. */ |
| 3479 | module_bug_finalize(info->hdr, info->sechdrs, mod); | 3522 | module_bug_finalize(info->hdr, info->sechdrs, mod); |
| 3480 | | 3523 | |
| 3481 | /* Set RO and NX regions */ | 3524 | module_enable_ro(mod, false); |
| 3482 | module_enable_ro(mod); | | |
| 3483 | module_enable_nx(mod); | 3525 | module_enable_nx(mod); |
| 3484 | | 3526 | |
| 3485 | /* Mark state as coming so strong_try_module_get() ignores us, | 3527 | /* Mark state as coming so strong_try_module_get() ignores us, |