Messages in this thread Patch in this message | | | From | Eddie Kovsky <> | Subject | [PATCH v2 1/3] module: verify address is read-only | Date | Fri, 17 Feb 2017 22:58:42 -0700 |
| |
Implement a mechanism to check if a module's address is in the rodata or ro_after_init sections. It mimics the exsiting functions that test if an address is inside a module's text section.
Signed-off-by: Eddie Kovsky <ewk@edkovsky.org> --- include/linux/module.h | 7 +++++++ kernel/module.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+)
diff --git a/include/linux/module.h b/include/linux/module.h index 0297c5cd7cdf..1608d3570ee2 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -492,7 +492,9 @@ static inline int module_is_live(struct module *mod)
struct module *__module_text_address(unsigned long addr); struct module *__module_address(unsigned long addr); +struct module *__module_ro_address(unsigned long addr); bool is_module_address(unsigned long addr); +bool is_module_ro_address(unsigned long addr); bool is_module_percpu_address(unsigned long addr); bool is_module_text_address(unsigned long addr);
@@ -645,6 +647,11 @@ static inline struct module *__module_address(unsigned long addr) return NULL; }
+static inline struct module *__module_ro_address(unsigned long addr) +{ + return NULL; +} + static inline struct module *__module_text_address(unsigned long addr) { return NULL; diff --git a/kernel/module.c b/kernel/module.c index 7eba6dea4f41..298cfe4645b1 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -4275,6 +4275,50 @@ struct module *__module_text_address(unsigned long addr) } EXPORT_SYMBOL_GPL(__module_text_address);
+/** + * is_module_text_ro_address - is this address inside read-only module code? + * @addr: the address to check. + * + */ +bool is_module_ro_address(unsigned long addr) +{ + bool ret; + + preempt_disable(); + ret = __module_ro_address(addr) != NULL; + preempt_enable(); + + return ret; +} + +/* + * __module_ro_address - get the module whose code contains a read-only address. + * @addr: the address. + * + * Must be called with preempt disabled or module mutex held so that + * module doesn't get freed during this. + */ +struct module *__module_ro_address(unsigned long addr) +{ + struct module *mod = __module_address(addr); + + if (mod) { + /* Make sure it's within the read-only section. */ + if (!within(addr, mod->init_layout.base, + mod->init_layout.ro_size) + && !within(addr, mod->core_layout.base, + mod->core_layout.ro_size)) + mod = NULL; + if (!within(addr, mod->init_layout.base, + mod->init_layout.ro_after_init_size) + && !within(addr, mod->core_layout.base, + mod->core_layout.ro_after_init_size)) + mod = NULL; + } + return mod; +} +EXPORT_SYMBOL_GPL(__module_ro_address); + /* Don't grab lock, we're oopsing. */ void print_modules(void) { -- 2.11.1
| |