@@ -1193,6 +1193,18 @@ void __weak module_arch_freeing_init(struct module *mod)
11931193{
11941194}
11951195
1196+ void * __module_writable_address (struct module * mod , void * loc )
1197+ {
1198+ for_class_mod_mem_type (type , text ) {
1199+ struct module_memory * mem = & mod -> mem [type ];
1200+
1201+ if (loc >= mem -> base && loc < mem -> base + mem -> size )
1202+ return loc + (mem -> rw_copy - mem -> base );
1203+ }
1204+
1205+ return loc ;
1206+ }
1207+
11961208static int module_memory_alloc (struct module * mod , enum mod_mem_type type )
11971209{
11981210 unsigned int size = PAGE_ALIGN (mod -> mem [type ].size );
@@ -1210,6 +1222,23 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type)
12101222 if (!ptr )
12111223 return - ENOMEM ;
12121224
1225+ mod -> mem [type ].base = ptr ;
1226+
1227+ if (execmem_is_rox (execmem_type )) {
1228+ ptr = vzalloc (size );
1229+
1230+ if (!ptr ) {
1231+ execmem_free (mod -> mem [type ].base );
1232+ return - ENOMEM ;
1233+ }
1234+
1235+ mod -> mem [type ].rw_copy = ptr ;
1236+ mod -> mem [type ].is_rox = true;
1237+ } else {
1238+ mod -> mem [type ].rw_copy = mod -> mem [type ].base ;
1239+ memset (mod -> mem [type ].base , 0 , size );
1240+ }
1241+
12131242 /*
12141243 * The pointer to these blocks of memory are stored on the module
12151244 * structure and we keep that around so long as the module is
@@ -1223,16 +1252,17 @@ static int module_memory_alloc(struct module *mod, enum mod_mem_type type)
12231252 */
12241253 kmemleak_not_leak (ptr );
12251254
1226- memset (ptr , 0 , size );
1227- mod -> mem [type ].base = ptr ;
1228-
12291255 return 0 ;
12301256}
12311257
12321258static void module_memory_free (struct module * mod , enum mod_mem_type type ,
12331259 bool unload_codetags )
12341260{
1235- void * ptr = mod -> mem [type ].base ;
1261+ struct module_memory * mem = & mod -> mem [type ];
1262+ void * ptr = mem -> base ;
1263+
1264+ if (mem -> is_rox )
1265+ vfree (mem -> rw_copy );
12361266
12371267 if (!unload_codetags && mod_mem_type_is_core_data (type ))
12381268 return ;
@@ -2255,6 +2285,7 @@ static int move_module(struct module *mod, struct load_info *info)
22552285 for_each_mod_mem_type (type ) {
22562286 if (!mod -> mem [type ].size ) {
22572287 mod -> mem [type ].base = NULL ;
2288+ mod -> mem [type ].rw_copy = NULL ;
22582289 continue ;
22592290 }
22602291
@@ -2271,11 +2302,14 @@ static int move_module(struct module *mod, struct load_info *info)
22712302 void * dest ;
22722303 Elf_Shdr * shdr = & info -> sechdrs [i ];
22732304 enum mod_mem_type type = shdr -> sh_entsize >> SH_ENTSIZE_TYPE_SHIFT ;
2305+ unsigned long offset = shdr -> sh_entsize & SH_ENTSIZE_OFFSET_MASK ;
2306+ unsigned long addr ;
22742307
22752308 if (!(shdr -> sh_flags & SHF_ALLOC ))
22762309 continue ;
22772310
2278- dest = mod -> mem [type ].base + (shdr -> sh_entsize & SH_ENTSIZE_OFFSET_MASK );
2311+ addr = (unsigned long )mod -> mem [type ].base + offset ;
2312+ dest = mod -> mem [type ].rw_copy + offset ;
22792313
22802314 if (shdr -> sh_type != SHT_NOBITS ) {
22812315 /*
@@ -2297,7 +2331,7 @@ static int move_module(struct module *mod, struct load_info *info)
22972331 * users of info can keep taking advantage and using the newly
22982332 * minted official memory area.
22992333 */
2300- shdr -> sh_addr = ( unsigned long ) dest ;
2334+ shdr -> sh_addr = addr ;
23012335 pr_debug ("\t0x%lx 0x%.8lx %s\n" , (long )shdr -> sh_addr ,
23022336 (long )shdr -> sh_size , info -> secstrings + shdr -> sh_name );
23032337 }
@@ -2445,8 +2479,17 @@ int __weak module_finalize(const Elf_Ehdr *hdr,
24452479 return 0 ;
24462480}
24472481
2482+ int __weak module_post_finalize (const Elf_Ehdr * hdr ,
2483+ const Elf_Shdr * sechdrs ,
2484+ struct module * me )
2485+ {
2486+ return 0 ;
2487+ }
2488+
24482489static int post_relocation (struct module * mod , const struct load_info * info )
24492490{
2491+ int ret ;
2492+
24502493 /* Sort exception table now relocations are done. */
24512494 sort_extable (mod -> extable , mod -> extable + mod -> num_exentries );
24522495
@@ -2458,7 +2501,24 @@ static int post_relocation(struct module *mod, const struct load_info *info)
24582501 add_kallsyms (mod , info );
24592502
24602503 /* Arch-specific module finalizing. */
2461- return module_finalize (info -> hdr , info -> sechdrs , mod );
2504+ ret = module_finalize (info -> hdr , info -> sechdrs , mod );
2505+ if (ret )
2506+ return ret ;
2507+
2508+ for_each_mod_mem_type (type ) {
2509+ struct module_memory * mem = & mod -> mem [type ];
2510+
2511+ if (mem -> is_rox ) {
2512+ if (!execmem_update_copy (mem -> base , mem -> rw_copy ,
2513+ mem -> size ))
2514+ return - ENOMEM ;
2515+
2516+ vfree (mem -> rw_copy );
2517+ mem -> rw_copy = NULL ;
2518+ }
2519+ }
2520+
2521+ return module_post_finalize (info -> hdr , info -> sechdrs , mod );
24622522}
24632523
24642524/* Call module constructors. */
0 commit comments