aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2015-11-25 18:15:08 -0500
committerJiri Kosina <jkosina@suse.cz>2015-12-04 16:46:26 -0500
commit85c898db6327353d38f3dd428457384cf81f83f8 (patch)
tree9a353d57bbf1702d75d2854305d10e4bc9b9fc22
parent7523e4dc5057e157212b4741abd6256e03404cf1 (diff)
module: clean up RO/NX handling.
Modules have three sections: text, rodata and writable data. The code handled the case where these overlapped, however they never can: debug_align() ensures they are always page-aligned. This is why we got away with manually traversing the pages in set_all_modules_text_rw() without rounding. We create three helper functions: frob_text(), frob_rodata() and frob_writable_data(). We then call these explicitly at every point, so it's clear what we're doing. We also expose module_enable_ro() and module_disable_ro() for livepatch to use. Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--include/linux/module.h4
-rw-r--r--kernel/module.c168
2 files changed, 81 insertions, 91 deletions
diff --git a/include/linux/module.h b/include/linux/module.h
index 6e68e8cf4d0d..4560d8f1545d 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -762,9 +762,13 @@ extern int module_sysfs_initialized;
762#ifdef CONFIG_DEBUG_SET_MODULE_RONX 762#ifdef CONFIG_DEBUG_SET_MODULE_RONX
763extern void set_all_modules_text_rw(void); 763extern void set_all_modules_text_rw(void);
764extern void set_all_modules_text_ro(void); 764extern void set_all_modules_text_ro(void);
765extern void module_enable_ro(const struct module *mod);
766extern void module_disable_ro(const struct module *mod);
765#else 767#else
766static inline void set_all_modules_text_rw(void) { } 768static inline void set_all_modules_text_rw(void) { }
767static inline void set_all_modules_text_ro(void) { } 769static inline void set_all_modules_text_ro(void) { }
770static inline void module_enable_ro(const struct module *mod) { }
771static inline void module_disable_ro(const struct module *mod) { }
768#endif 772#endif
769 773
770#ifdef CONFIG_GENERIC_BUG 774#ifdef CONFIG_GENERIC_BUG
diff --git a/kernel/module.c b/kernel/module.c
index a0a3d6d9d5e8..77212128f34a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -80,15 +80,6 @@
80# define debug_align(X) (X) 80# define debug_align(X) (X)
81#endif 81#endif
82 82
83/*
84 * Given BASE and SIZE this macro calculates the number of pages the
85 * memory regions occupies
86 */
87#define MOD_NUMBER_OF_PAGES(BASE, SIZE) (((SIZE) > 0) ? \
88 (PFN_DOWN((unsigned long)(BASE) + (SIZE) - 1) - \
89 PFN_DOWN((unsigned long)BASE) + 1) \
90 : (0UL))
91
92/* If this is set, the section belongs in the init part of the module */ 83/* If this is set, the section belongs in the init part of the module */
93#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) 84#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
94 85
@@ -1858,74 +1849,75 @@ static void mod_sysfs_teardown(struct module *mod)
1858/* 1849/*
1859 * LKM RO/NX protection: protect module's text/ro-data 1850 * LKM RO/NX protection: protect module's text/ro-data
1860 * from modification and any data from execution. 1851 * from modification and any data from execution.
1852 *
1853 * General layout of module is:
1854 * [text] [read-only-data] [writable data]
1855 * text_size -----^ ^ ^
1856 * ro_size ------------------------| |
1857 * size -------------------------------------------|
1858 *
1859 * These values are always page-aligned (as is base)
1861 */ 1860 */
1862void set_page_attributes(void *start, void *end, int (*set)(unsigned long start, int num_pages)) 1861static void frob_text(const struct module_layout *layout,
1862 int (*set_memory)(unsigned long start, int num_pages))
1863{ 1863{
1864 unsigned long begin_pfn = PFN_DOWN((unsigned long)start); 1864 BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
1865 unsigned long end_pfn = PFN_DOWN((unsigned long)end); 1865 BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
1866 1866 set_memory((unsigned long)layout->base,
1867 if (end_pfn > begin_pfn) 1867 layout->text_size >> PAGE_SHIFT);
1868 set(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn);
1869} 1868}
1870 1869
1871static void set_section_ro_nx(void *base, 1870static void frob_rodata(const struct module_layout *layout,
1872 unsigned long text_size, 1871 int (*set_memory)(unsigned long start, int num_pages))
1873 unsigned long ro_size,
1874 unsigned long total_size,
1875 int (*set_ro)(unsigned long start, int num_pages),
1876 int (*set_nx)(unsigned long start, int num_pages))
1877{ 1872{
1878 /* begin and end PFNs of the current subsection */ 1873 BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
1879 unsigned long begin_pfn; 1874 BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1));
1880 unsigned long end_pfn; 1875 BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
1881 1876 set_memory((unsigned long)layout->base + layout->text_size,
1882 /* 1877 (layout->ro_size - layout->text_size) >> PAGE_SHIFT);
1883 * Set RO for module text and RO-data: 1878}
1884 * - Always protect first page.
1885 * - Do not protect last partial page.
1886 */
1887 if (ro_size > 0)
1888 set_page_attributes(base, base + ro_size, set_ro);
1889 1879
1890 /* 1880static void frob_writable_data(const struct module_layout *layout,
1891 * Set NX permissions for module data: 1881 int (*set_memory)(unsigned long start, int num_pages))
1892 * - Do not protect first partial page. 1882{
1893 * - Always protect last page. 1883 BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1));
1894 */ 1884 BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1));
1895 if (total_size > text_size) { 1885 BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1));
1896 begin_pfn = PFN_UP((unsigned long)base + text_size); 1886 set_memory((unsigned long)layout->base + layout->ro_size,
1897 end_pfn = PFN_UP((unsigned long)base + total_size); 1887 (layout->size - layout->ro_size) >> PAGE_SHIFT);
1898 if (end_pfn > begin_pfn)
1899 set_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn);
1900 }
1901} 1888}
1902 1889
1903static void set_module_core_ro_nx(struct module *mod) 1890/* livepatching wants to disable read-only so it can frob module. */
1891void module_disable_ro(const struct module *mod)
1904{ 1892{
1905 set_section_ro_nx(mod->core_layout.base, mod->core_layout.text_size, 1893 frob_text(&mod->core_layout, set_memory_rw);
1906 mod->core_layout.ro_size, mod->core_layout.size, 1894 frob_rodata(&mod->core_layout, set_memory_rw);
1907 set_memory_ro, set_memory_nx); 1895 frob_text(&mod->init_layout, set_memory_rw);
1896 frob_rodata(&mod->init_layout, set_memory_rw);
1908} 1897}
1909 1898
1910static void unset_module_core_ro_nx(struct module *mod) 1899void module_enable_ro(const struct module *mod)
1911{ 1900{
1912 set_section_ro_nx(mod->core_layout.base, mod->core_layout.text_size, 1901 frob_text(&mod->core_layout, set_memory_ro);
1913 mod->core_layout.ro_size, mod->core_layout.size, 1902 frob_rodata(&mod->core_layout, set_memory_ro);
1914 set_memory_rw, set_memory_x); 1903 frob_text(&mod->init_layout, set_memory_ro);
1904 frob_rodata(&mod->init_layout, set_memory_ro);
1915} 1905}
1916 1906
1917static void set_module_init_ro_nx(struct module *mod) 1907static void module_enable_nx(const struct module *mod)
1918{ 1908{
1919 set_section_ro_nx(mod->init_layout.base, mod->init_layout.text_size, 1909 frob_rodata(&mod->core_layout, set_memory_nx);
1920 mod->init_layout.ro_size, mod->init_layout.size, 1910 frob_writable_data(&mod->core_layout, set_memory_nx);
1921 set_memory_ro, set_memory_nx); 1911 frob_rodata(&mod->init_layout, set_memory_nx);
1912 frob_writable_data(&mod->init_layout, set_memory_nx);
1922} 1913}
1923 1914
1924static void unset_module_init_ro_nx(struct module *mod) 1915static void module_disable_nx(const struct module *mod)
1925{ 1916{
1926 set_section_ro_nx(mod->init_layout.base, mod->init_layout.text_size, 1917 frob_rodata(&mod->core_layout, set_memory_x);
1927 mod->init_layout.ro_size, mod->init_layout.size, 1918 frob_writable_data(&mod->core_layout, set_memory_x);
1928 set_memory_rw, set_memory_x); 1919 frob_rodata(&mod->init_layout, set_memory_x);
1920 frob_writable_data(&mod->init_layout, set_memory_x);
1929} 1921}
1930 1922
1931/* Iterate through all modules and set each module's text as RW */ 1923/* Iterate through all modules and set each module's text as RW */
@@ -1937,16 +1929,9 @@ void set_all_modules_text_rw(void)
1937 list_for_each_entry_rcu(mod, &modules, list) { 1929 list_for_each_entry_rcu(mod, &modules, list) {
1938 if (mod->state == MODULE_STATE_UNFORMED) 1930 if (mod->state == MODULE_STATE_UNFORMED)
1939 continue; 1931 continue;
1940 if ((mod->core_layout.base) && (mod->core_layout.text_size)) { 1932
1941 set_page_attributes(mod->core_layout.base, 1933 frob_text(&mod->core_layout, set_memory_rw);
1942 mod->core_layout.base + mod->core_layout.text_size, 1934 frob_text(&mod->init_layout, set_memory_rw);
1943 set_memory_rw);
1944 }
1945 if ((mod->init_layout.base) && (mod->init_layout.text_size)) {
1946 set_page_attributes(mod->init_layout.base,
1947 mod->init_layout.base + mod->init_layout.text_size,
1948 set_memory_rw);
1949 }
1950 } 1935 }
1951 mutex_unlock(&module_mutex); 1936 mutex_unlock(&module_mutex);
1952} 1937}
@@ -1960,24 +1945,25 @@ void set_all_modules_text_ro(void)
1960 list_for_each_entry_rcu(mod, &modules, list) { 1945 list_for_each_entry_rcu(mod, &modules, list) {
1961 if (mod->state == MODULE_STATE_UNFORMED) 1946 if (mod->state == MODULE_STATE_UNFORMED)
1962 continue; 1947 continue;
1963 if ((mod->core_layout.base) && (mod->core_layout.text_size)) { 1948
1964 set_page_attributes(mod->core_layout.base, 1949 frob_text(&mod->core_layout, set_memory_ro);
1965 mod->core_layout.base + mod->core_layout.text_size, 1950 frob_text(&mod->init_layout, set_memory_ro);
1966 set_memory_ro);
1967 }
1968 if ((mod->init_layout.base) && (mod->init_layout.text_size)) {
1969 set_page_attributes(mod->init_layout.base,
1970 mod->init_layout.base + mod->init_layout.text_size,
1971 set_memory_ro);
1972 }
1973 } 1951 }
1974 mutex_unlock(&module_mutex); 1952 mutex_unlock(&module_mutex);
1975} 1953}
1954
1955static void disable_ro_nx(const struct module_layout *layout)
1956{
1957 frob_text(layout, set_memory_rw);
1958 frob_rodata(layout, set_memory_rw);
1959 frob_rodata(layout, set_memory_x);
1960 frob_writable_data(layout, set_memory_x);
1961}
1962
1976#else 1963#else
1977static void set_module_core_ro_nx(struct module *mod) { } 1964static void disable_ro_nx(const struct module_layout *layout) { }
1978static void set_module_init_ro_nx(struct module *mod) { } 1965static void module_enable_nx(const struct module *mod) { }
1979static void unset_module_core_ro_nx(struct module *mod) { } 1966static void module_disable_nx(const struct module *mod) { }
1980static void unset_module_init_ro_nx(struct module *mod) { }
1981#endif 1967#endif
1982 1968
1983void __weak module_memfree(void *module_region) 1969void __weak module_memfree(void *module_region)
@@ -2029,8 +2015,8 @@ static void free_module(struct module *mod)
2029 synchronize_sched(); 2015 synchronize_sched();
2030 mutex_unlock(&module_mutex); 2016 mutex_unlock(&module_mutex);
2031 2017
2032 /* This may be NULL, but that's OK */ 2018 /* This may be empty, but that's OK */
2033 unset_module_init_ro_nx(mod); 2019 disable_ro_nx(&mod->init_layout);
2034 module_arch_freeing_init(mod); 2020 module_arch_freeing_init(mod);
2035 module_memfree(mod->init_layout.base); 2021 module_memfree(mod->init_layout.base);
2036 kfree(mod->args); 2022 kfree(mod->args);
@@ -2040,7 +2026,7 @@ static void free_module(struct module *mod)
2040 lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size); 2026 lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size);
2041 2027
2042 /* Finally, free the core (containing the module structure) */ 2028 /* Finally, free the core (containing the module structure) */
2043 unset_module_core_ro_nx(mod); 2029 disable_ro_nx(&mod->core_layout);
2044 module_memfree(mod->core_layout.base); 2030 module_memfree(mod->core_layout.base);
2045 2031
2046#ifdef CONFIG_MPU 2032#ifdef CONFIG_MPU
@@ -3275,7 +3261,7 @@ static noinline int do_init_module(struct module *mod)
3275 mod->strtab = mod->core_strtab; 3261 mod->strtab = mod->core_strtab;
3276#endif 3262#endif
3277 mod_tree_remove_init(mod); 3263 mod_tree_remove_init(mod);
3278 unset_module_init_ro_nx(mod); 3264 disable_ro_nx(&mod->init_layout);
3279 module_arch_freeing_init(mod); 3265 module_arch_freeing_init(mod);
3280 mod->init_layout.base = NULL; 3266 mod->init_layout.base = NULL;
3281 mod->init_layout.size = 0; 3267 mod->init_layout.size = 0;
@@ -3370,8 +3356,8 @@ static int complete_formation(struct module *mod, struct load_info *info)
3370 module_bug_finalize(info->hdr, info->sechdrs, mod); 3356 module_bug_finalize(info->hdr, info->sechdrs, mod);
3371 3357
3372 /* Set RO and NX regions */ 3358 /* Set RO and NX regions */
3373 set_module_init_ro_nx(mod); 3359 module_enable_ro(mod);
3374 set_module_core_ro_nx(mod); 3360 module_enable_nx(mod);
3375 3361
3376 /* Mark state as coming so strong_try_module_get() ignores us, 3362 /* Mark state as coming so strong_try_module_get() ignores us,
3377 * but kallsyms etc. can see us. */ 3363 * but kallsyms etc. can see us. */
@@ -3536,8 +3522,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
3536 MODULE_STATE_GOING, mod); 3522 MODULE_STATE_GOING, mod);
3537 3523
3538 /* we can't deallocate the module until we clear memory protection */ 3524 /* we can't deallocate the module until we clear memory protection */
3539 unset_module_init_ro_nx(mod); 3525 module_disable_ro(mod);
3540 unset_module_core_ro_nx(mod); 3526 module_disable_nx(mod);
3541 3527
3542 ddebug_cleanup: 3528 ddebug_cleanup:
3543 dynamic_debug_remove(info->debug); 3529 dynamic_debug_remove(info->debug);