aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2015-11-25 18:12:08 -0500
committerJiri Kosina <jkosina@suse.cz>2015-12-04 16:46:24 -0500
commit20ef10c1b3068f105004e247d8e7dd8120fa4b9a (patch)
tree08c6a0745a46101837dcd34425e9c5716a294b11 /kernel/module.c
parent78c4a49a69e910a162b05e4e8727b9bdbf948f13 (diff)
module: Use the same logic for setting and unsetting RO/NX
When setting a module's RO and NX permissions, set_section_ro_nx() is used, but when clearing them, unset_module_{init,core}_ro_nx() are used. The unset functions don't have the same checks the set function has for partial page protections. It's probably harmless, but it's still confusingly asymmetrical. Instead, use the same logic to do both. Also add some new set_module_{init,core}_ro_nx() helper functions for more symmetry with the unset functions. Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c57
1 files changed, 30 insertions, 27 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 8f051a106676..14b224967e7b 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1886,7 +1886,9 @@ void set_page_attributes(void *start, void *end, int (*set)(unsigned long start,
1886static void set_section_ro_nx(void *base, 1886static void set_section_ro_nx(void *base,
1887 unsigned long text_size, 1887 unsigned long text_size,
1888 unsigned long ro_size, 1888 unsigned long ro_size,
1889 unsigned long total_size) 1889 unsigned long total_size,
1890 int (*set_ro)(unsigned long start, int num_pages),
1891 int (*set_nx)(unsigned long start, int num_pages))
1890{ 1892{
1891 /* begin and end PFNs of the current subsection */ 1893 /* begin and end PFNs of the current subsection */
1892 unsigned long begin_pfn; 1894 unsigned long begin_pfn;
@@ -1898,7 +1900,7 @@ static void set_section_ro_nx(void *base,
1898 * - Do not protect last partial page. 1900 * - Do not protect last partial page.
1899 */ 1901 */
1900 if (ro_size > 0) 1902 if (ro_size > 0)
1901 set_page_attributes(base, base + ro_size, set_memory_ro); 1903 set_page_attributes(base, base + ro_size, set_ro);
1902 1904
1903 /* 1905 /*
1904 * Set NX permissions for module data: 1906 * Set NX permissions for module data:
@@ -1909,28 +1911,36 @@ static void set_section_ro_nx(void *base,
1909 begin_pfn = PFN_UP((unsigned long)base + text_size); 1911 begin_pfn = PFN_UP((unsigned long)base + text_size);
1910 end_pfn = PFN_UP((unsigned long)base + total_size); 1912 end_pfn = PFN_UP((unsigned long)base + total_size);
1911 if (end_pfn > begin_pfn) 1913 if (end_pfn > begin_pfn)
1912 set_memory_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn); 1914 set_nx(begin_pfn << PAGE_SHIFT, end_pfn - begin_pfn);
1913 } 1915 }
1914} 1916}
1915 1917
1918static void set_module_core_ro_nx(struct module *mod)
1919{
1920 set_section_ro_nx(mod->module_core, mod->core_text_size,
1921 mod->core_ro_size, mod->core_size,
1922 set_memory_ro, set_memory_nx);
1923}
1924
1916static void unset_module_core_ro_nx(struct module *mod) 1925static void unset_module_core_ro_nx(struct module *mod)
1917{ 1926{
1918 set_page_attributes(mod->module_core + mod->core_text_size, 1927 set_section_ro_nx(mod->module_core, mod->core_text_size,
1919 mod->module_core + mod->core_size, 1928 mod->core_ro_size, mod->core_size,
1920 set_memory_x); 1929 set_memory_rw, set_memory_x);
1921 set_page_attributes(mod->module_core, 1930}
1922 mod->module_core + mod->core_ro_size, 1931
1923 set_memory_rw); 1932static void set_module_init_ro_nx(struct module *mod)
1933{
1934 set_section_ro_nx(mod->module_init, mod->init_text_size,
1935 mod->init_ro_size, mod->init_size,
1936 set_memory_ro, set_memory_nx);
1924} 1937}
1925 1938
1926static void unset_module_init_ro_nx(struct module *mod) 1939static void unset_module_init_ro_nx(struct module *mod)
1927{ 1940{
1928 set_page_attributes(mod->module_init + mod->init_text_size, 1941 set_section_ro_nx(mod->module_init, mod->init_text_size,
1929 mod->module_init + mod->init_size, 1942 mod->init_ro_size, mod->init_size,
1930 set_memory_x); 1943 set_memory_rw, set_memory_x);
1931 set_page_attributes(mod->module_init,
1932 mod->module_init + mod->init_ro_size,
1933 set_memory_rw);
1934} 1944}
1935 1945
1936/* Iterate through all modules and set each module's text as RW */ 1946/* Iterate through all modules and set each module's text as RW */
@@ -1979,7 +1989,8 @@ void set_all_modules_text_ro(void)
1979 mutex_unlock(&module_mutex); 1989 mutex_unlock(&module_mutex);
1980} 1990}
1981#else 1991#else
1982static inline void set_section_ro_nx(void *base, unsigned long text_size, unsigned long ro_size, unsigned long total_size) { } 1992static void set_module_core_ro_nx(struct module *mod) { }
1993static void set_module_init_ro_nx(struct module *mod) { }
1983static void unset_module_core_ro_nx(struct module *mod) { } 1994static void unset_module_core_ro_nx(struct module *mod) { }
1984static void unset_module_init_ro_nx(struct module *mod) { } 1995static void unset_module_init_ro_nx(struct module *mod) { }
1985#endif 1996#endif
@@ -3373,17 +3384,9 @@ static int complete_formation(struct module *mod, struct load_info *info)
3373 /* This relies on module_mutex for list integrity. */ 3384 /* This relies on module_mutex for list integrity. */
3374 module_bug_finalize(info->hdr, info->sechdrs, mod); 3385 module_bug_finalize(info->hdr, info->sechdrs, mod);
3375 3386
3376 /* Set RO and NX regions for core */ 3387 /* Set RO and NX regions */
3377 set_section_ro_nx(mod->module_core, 3388 set_module_init_ro_nx(mod);
3378 mod->core_text_size, 3389 set_module_core_ro_nx(mod);
3379 mod->core_ro_size,
3380 mod->core_size);
3381
3382 /* Set RO and NX regions for init */
3383 set_section_ro_nx(mod->module_init,
3384 mod->init_text_size,
3385 mod->init_ro_size,
3386 mod->init_size);
3387 3390
3388 /* Mark state as coming so strong_try_module_get() ignores us, 3391 /* Mark state as coming so strong_try_module_get() ignores us,
3389 * but kallsyms etc. can see us. */ 3392 * but kallsyms etc. can see us. */