@@ -1857,10 +1857,11 @@ static void mod_sysfs_teardown(struct module *mod)
18571857 * from modification and any data from execution.
18581858 *
18591859 * General layout of module is:
1860- * [text] [read-only-data] [writable data]
1861- * text_size -----^ ^ ^
1862- * ro_size ------------------------| |
1863- * size -------------------------------------------|
1860+ * [text] [read-only-data] [ro-after-init] [writable data]
1861+ * text_size -----^ ^ ^ ^
1862+ * ro_size ------------------------| | |
1863+ * ro_after_init_size -----------------------------| |
1864+ * size -----------------------------------------------------------|
18641865 *
18651866 * These values are always page-aligned (as is base)
18661867 */
@@ -1883,36 +1884,51 @@ static void frob_rodata(const struct module_layout *layout,
18831884 (layout -> ro_size - layout -> text_size ) >> PAGE_SHIFT );
18841885}
18851886
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+
18861897static void frob_writable_data (const struct module_layout * layout ,
18871898 int (* set_memory )(unsigned long start , int num_pages ))
18881899{
18891900 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 ));
18911902 BUG_ON ((unsigned long )layout -> size & (PAGE_SIZE - 1 ));
1892- set_memory ((unsigned long )layout -> base + layout -> ro_size ,
1893- (layout -> size - layout -> ro_size ) >> PAGE_SHIFT );
1903+ set_memory ((unsigned long )layout -> base + layout -> ro_after_init_size ,
1904+ (layout -> size - layout -> ro_after_init_size ) >> PAGE_SHIFT );
18941905}
18951906
18961907/* livepatching wants to disable read-only so it can frob module. */
18971908void module_disable_ro (const struct module * mod )
18981909{
18991910 frob_text (& mod -> core_layout , set_memory_rw );
19001911 frob_rodata (& mod -> core_layout , set_memory_rw );
1912+ frob_ro_after_init (& mod -> core_layout , set_memory_rw );
19011913 frob_text (& mod -> init_layout , set_memory_rw );
19021914 frob_rodata (& mod -> init_layout , set_memory_rw );
19031915}
19041916
1905- void module_enable_ro (const struct module * mod )
1917+ void module_enable_ro (const struct module * mod , bool after_init )
19061918{
19071919 frob_text (& mod -> core_layout , set_memory_ro );
19081920 frob_rodata (& mod -> core_layout , set_memory_ro );
19091921 frob_text (& mod -> init_layout , set_memory_ro );
19101922 frob_rodata (& mod -> init_layout , set_memory_ro );
1923+
1924+ if (after_init )
1925+ frob_ro_after_init (& mod -> core_layout , set_memory_ro );
19111926}
19121927
19131928static void module_enable_nx (const struct module * mod )
19141929{
19151930 frob_rodata (& mod -> core_layout , set_memory_nx );
1931+ frob_ro_after_init (& mod -> core_layout , set_memory_nx );
19161932 frob_writable_data (& mod -> core_layout , set_memory_nx );
19171933 frob_rodata (& mod -> init_layout , set_memory_nx );
19181934 frob_writable_data (& mod -> init_layout , set_memory_nx );
@@ -1921,6 +1937,7 @@ static void module_enable_nx(const struct module *mod)
19211937static void module_disable_nx (const struct module * mod )
19221938{
19231939 frob_rodata (& mod -> core_layout , set_memory_x );
1940+ frob_ro_after_init (& mod -> core_layout , set_memory_x );
19241941 frob_writable_data (& mod -> core_layout , set_memory_x );
19251942 frob_rodata (& mod -> init_layout , set_memory_x );
19261943 frob_writable_data (& mod -> init_layout , set_memory_x );
@@ -1963,6 +1980,8 @@ static void disable_ro_nx(const struct module_layout *layout)
19631980 frob_text (layout , set_memory_rw );
19641981 frob_rodata (layout , set_memory_rw );
19651982 frob_rodata (layout , set_memory_x );
1983+ frob_ro_after_init (layout , set_memory_rw );
1984+ frob_ro_after_init (layout , set_memory_x );
19661985 frob_writable_data (layout , set_memory_x );
19671986}
19681987
@@ -2305,6 +2324,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
23052324 * finder in the two loops below */
23062325 { SHF_EXECINSTR | SHF_ALLOC , ARCH_SHF_SMALL },
23072326 { SHF_ALLOC , SHF_WRITE | ARCH_SHF_SMALL },
2327+ { SHF_RO_AFTER_INIT | SHF_ALLOC , ARCH_SHF_SMALL },
23082328 { SHF_WRITE | SHF_ALLOC , ARCH_SHF_SMALL },
23092329 { ARCH_SHF_SMALL | SHF_ALLOC , 0 }
23102330 };
@@ -2336,7 +2356,11 @@ static void layout_sections(struct module *mod, struct load_info *info)
23362356 mod -> core_layout .size = debug_align (mod -> core_layout .size );
23372357 mod -> core_layout .ro_size = mod -> core_layout .size ;
23382358 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 */
23402364 mod -> core_layout .size = debug_align (mod -> core_layout .size );
23412365 break ;
23422366 }
@@ -2366,7 +2390,14 @@ static void layout_sections(struct module *mod, struct load_info *info)
23662390 mod -> init_layout .size = debug_align (mod -> init_layout .size );
23672391 mod -> init_layout .ro_size = mod -> init_layout .size ;
23682392 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 */
23702401 mod -> init_layout .size = debug_align (mod -> init_layout .size );
23712402 break ;
23722403 }
@@ -3193,6 +3224,7 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
31933224{
31943225 /* Module within temporary copy. */
31953226 struct module * mod ;
3227+ unsigned int ndx ;
31963228 int err ;
31973229
31983230 mod = setup_load_info (info , flags );
@@ -3215,6 +3247,15 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
32153247 /* We will do a special allocation for per-cpu sections later. */
32163248 info -> sechdrs [info -> index .pcpu ].sh_flags &= ~(unsigned long )SHF_ALLOC ;
32173249
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+
32183259 /* Determine total sizes, and put offsets in sh_entsize. For now
32193260 this is done generically; there doesn't appear to be any
32203261 special cases for the architectures. */
@@ -3381,12 +3422,14 @@ static noinline int do_init_module(struct module *mod)
33813422 /* Switch to core kallsyms now init is done: kallsyms may be walking! */
33823423 rcu_assign_pointer (mod -> kallsyms , & mod -> core_kallsyms );
33833424#endif
3425+ module_enable_ro (mod , true);
33843426 mod_tree_remove_init (mod );
33853427 disable_ro_nx (& mod -> init_layout );
33863428 module_arch_freeing_init (mod );
33873429 mod -> init_layout .base = NULL ;
33883430 mod -> init_layout .size = 0 ;
33893431 mod -> init_layout .ro_size = 0 ;
3432+ mod -> init_layout .ro_after_init_size = 0 ;
33903433 mod -> init_layout .text_size = 0 ;
33913434 /*
33923435 * 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)
34783521 /* This relies on module_mutex for list integrity. */
34793522 module_bug_finalize (info -> hdr , info -> sechdrs , mod );
34803523
3481- /* Set RO and NX regions */
3482- module_enable_ro (mod );
3524+ module_enable_ro (mod , false);
34833525 module_enable_nx (mod );
34843526
34853527 /* Mark state as coming so strong_try_module_get() ignores us,
0 commit comments