aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJessica Yu <jeyu@redhat.com>2016-07-26 22:36:21 -0400
committerRusty Russell <rusty@rustcorp.com.au>2016-08-03 20:46:55 -0400
commit444d13ff10fb13bc3e64859c3cf9ce43dcfeb075 (patch)
treeab35e195fe3daeae0bd87f6f5bd7cc1cf07fd86a
parentbdc9f373551dd3f1e6fae1618f2394ee9bc7db2e (diff)
modules: add ro_after_init support
Add ro_after_init support for modules by adding a new page-aligned section in the module layout (after rodata) for ro_after_init data and enabling RO protection for that section after module init runs. Signed-off-by: Jessica Yu <jeyu@redhat.com> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--include/linux/module.h6
-rw-r--r--include/uapi/linux/elf.h1
-rw-r--r--kernel/livepatch/core.c2
-rw-r--r--kernel/module.c66
4 files changed, 60 insertions, 15 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index f95ed243a4de..0c3207d26ac0 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -298,6 +298,8 @@ struct module_layout {
298 unsigned int text_size; 298 unsigned int text_size;
299 /* Size of RO section of the module (text+rodata) */ 299 /* Size of RO section of the module (text+rodata) */
300 unsigned int ro_size; 300 unsigned int ro_size;
301 /* Size of RO after init section */
302 unsigned int ro_after_init_size;
301 303
302#ifdef CONFIG_MODULES_TREE_LOOKUP 304#ifdef CONFIG_MODULES_TREE_LOOKUP
303 struct mod_tree_node mtn; 305 struct mod_tree_node mtn;
@@ -765,12 +767,12 @@ extern int module_sysfs_initialized;
765#ifdef CONFIG_DEBUG_SET_MODULE_RONX 767#ifdef CONFIG_DEBUG_SET_MODULE_RONX
766extern void set_all_modules_text_rw(void); 768extern void set_all_modules_text_rw(void);
767extern void set_all_modules_text_ro(void); 769extern void set_all_modules_text_ro(void);
768extern void module_enable_ro(const struct module *mod); 770extern void module_enable_ro(const struct module *mod, bool after_init);
769extern void module_disable_ro(const struct module *mod); 771extern void module_disable_ro(const struct module *mod);
770#else 772#else
771static inline void set_all_modules_text_rw(void) { } 773static inline void set_all_modules_text_rw(void) { }
772static inline void set_all_modules_text_ro(void) { } 774static inline void set_all_modules_text_ro(void) { }
773static inline void module_enable_ro(const struct module *mod) { } 775static inline void module_enable_ro(const struct module *mod, bool after_init) { }
774static inline void module_disable_ro(const struct module *mod) { } 776static inline void module_disable_ro(const struct module *mod) { }
775#endif 777#endif
776 778
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index cb4a72f888d5..70b172ba41ce 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -286,6 +286,7 @@ typedef struct elf64_phdr {
286#define SHF_ALLOC 0x2 286#define SHF_ALLOC 0x2
287#define SHF_EXECINSTR 0x4 287#define SHF_EXECINSTR 0x4
288#define SHF_RELA_LIVEPATCH 0x00100000 288#define SHF_RELA_LIVEPATCH 0x00100000
289#define SHF_RO_AFTER_INIT 0x00200000
289#define SHF_MASKPROC 0xf0000000 290#define SHF_MASKPROC 0xf0000000
290 291
291/* special section indexes */ 292/* special section indexes */
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 5c2bc1052691..8bbe50704621 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -309,7 +309,7 @@ static int klp_write_object_relocations(struct module *pmod,
309 break; 309 break;
310 } 310 }
311 311
312 module_enable_ro(pmod); 312 module_enable_ro(pmod, true);
313 return ret; 313 return ret;
314} 314}
315 315
diff --git a/kernel/module.c b/kernel/module.c
index c91c2fdca2e6..205a71a97852 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1857,10 +1857,11 @@ static void mod_sysfs_teardown(struct module *mod)
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,
1883 (layout->ro_size - layout->text_size) >> PAGE_SHIFT); 1884 (layout->ro_size - layout->text_size) >> PAGE_SHIFT);
1884} 1885}
1885 1886
1887static 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
1886static void frob_writable_data(const struct module_layout *layout, 1897static 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)
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
1905void module_enable_ro(const struct module *mod) 1917void 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
1913static void module_enable_nx(const struct module *mod) 1928static 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)
1921static void module_disable_nx(const struct module *mod) 1937static 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)
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)
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)
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)
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)
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)
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)
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)
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,