* [PATCH v2 0/3] provide check for ro_after_init memory sections
@ 2017-02-18 5:58 Eddie Kovsky
2017-02-18 5:58 ` [PATCH v2 1/3] module: verify address is read-only Eddie Kovsky
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Eddie Kovsky @ 2017-02-18 5:58 UTC (permalink / raw)
To: jeyu, rusty, keescook, kys, haiyangz, sthemmin
Cc: linux-kernel, kernel-hardening
Provide a mechansim for other functions to verify that their arguments
are read-only. Use this mechansim in the vmbus register functions to
reject arguments that fail this test.
This implements a suggestion made by Kees Cook for the Kernel Self
Protection Project:
* provide mechanism to check for ro_after_init memory areas, and
reject structures not marked ro_after_init in vmbus_register()
http://www.openwall.com/lists/kernel-hardening/2017/02/04/1
I have successfully compiled this series on next-20170215 for x86.
Eddie Kovsky (3):
module: verify address is read-only
extable: verify address is read-only
Make vmbus register arguments read-only
drivers/hv/vmbus_drv.c | 10 ++++++++++
include/linux/kernel.h | 2 ++
include/linux/module.h | 7 +++++++
kernel/extable.c | 29 +++++++++++++++++++++++++++++
kernel/module.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 92 insertions(+)
--
2.11.1
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v2 1/3] module: verify address is read-only 2017-02-18 5:58 [PATCH v2 0/3] provide check for ro_after_init memory sections Eddie Kovsky @ 2017-02-18 5:58 ` Eddie Kovsky 2017-02-20 17:14 ` Stephen Hemminger 2017-02-26 17:42 ` Jessica Yu 2017-02-18 5:58 ` [PATCH v2 2/3] extable: " Eddie Kovsky 2017-02-18 5:58 ` [PATCH v2 3/3] Make vmbus register arguments read-only Eddie Kovsky 2 siblings, 2 replies; 12+ messages in thread From: Eddie Kovsky @ 2017-02-18 5:58 UTC (permalink / raw) To: jeyu, rusty, keescook, kys, haiyangz, sthemmin Cc: linux-kernel, kernel-hardening 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 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] module: verify address is read-only 2017-02-18 5:58 ` [PATCH v2 1/3] module: verify address is read-only Eddie Kovsky @ 2017-02-20 17:14 ` Stephen Hemminger 2017-02-21 20:32 ` Kees Cook 2017-02-26 17:42 ` Jessica Yu 1 sibling, 1 reply; 12+ messages in thread From: Stephen Hemminger @ 2017-02-20 17:14 UTC (permalink / raw) To: Eddie Kovsky Cc: jeyu, rusty, keescook, KY Srinivasan, Haiyang Zhang, Stephen Hemminger, linux-kernel, kernel-hardening On Fri, 17 Feb 2017 21:58:42 -0800 "Eddie Kovsky" <ewk@edkovsky.org> wrote: > 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> I don't see the point of this for many of the hyper-v functions. They are only called from a small number of places, and this can be validated by code inspection. Adding this seems just seems to be code bloat to me. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] module: verify address is read-only 2017-02-20 17:14 ` Stephen Hemminger @ 2017-02-21 20:32 ` Kees Cook 2017-02-21 20:51 ` Stephen Hemminger 0 siblings, 1 reply; 12+ messages in thread From: Kees Cook @ 2017-02-21 20:32 UTC (permalink / raw) To: Stephen Hemminger Cc: Eddie Kovsky, Jessica Yu, Rusty Russell, KY Srinivasan, Haiyang Zhang, Stephen Hemminger, LKML, kernel-hardening@lists.openwall.com On Mon, Feb 20, 2017 at 9:14 AM, Stephen Hemminger <stephen@networkplumber.org> wrote: > On Fri, 17 Feb 2017 21:58:42 -0800 > "Eddie Kovsky" <ewk@edkovsky.org> wrote: > >> 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> > > I don't see the point of this for many of the hyper-v functions. > They are only called from a small number of places, and this can be validated > by code inspection. Adding this seems just seems to be code bloat to me. I think it has value in that it effectively blocks any way for non-ro_after_init structures from being passed into these functions. Since there are so few callers now, it's the perfect place to add this. -Kees -- Kees Cook Pixel Security ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] module: verify address is read-only 2017-02-21 20:32 ` Kees Cook @ 2017-02-21 20:51 ` Stephen Hemminger 0 siblings, 0 replies; 12+ messages in thread From: Stephen Hemminger @ 2017-02-21 20:51 UTC (permalink / raw) To: Kees Cook Cc: Eddie Kovsky, Jessica Yu, Rusty Russell, KY Srinivasan, Haiyang Zhang, Stephen Hemminger, LKML, kernel-hardening@lists.openwall.com On Tue, 21 Feb 2017 12:32:16 -0800 Kees Cook <keescook@chromium.org> wrote: > On Mon, Feb 20, 2017 at 9:14 AM, Stephen Hemminger > <stephen@networkplumber.org> wrote: > > On Fri, 17 Feb 2017 21:58:42 -0800 > > "Eddie Kovsky" <ewk@edkovsky.org> wrote: > > > >> 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> > > > > I don't see the point of this for many of the hyper-v functions. > > They are only called from a small number of places, and this can be validated > > by code inspection. Adding this seems just seems to be code bloat to me. > > I think it has value in that it effectively blocks any way for > non-ro_after_init structures from being passed into these functions. > Since there are so few callers now, it's the perfect place to add > this. > > -Kees > Maybe for a more used API, but for such a corner case it is code bloat. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] module: verify address is read-only 2017-02-18 5:58 ` [PATCH v2 1/3] module: verify address is read-only Eddie Kovsky 2017-02-20 17:14 ` Stephen Hemminger @ 2017-02-26 17:42 ` Jessica Yu 1 sibling, 0 replies; 12+ messages in thread From: Jessica Yu @ 2017-02-26 17:42 UTC (permalink / raw) To: Eddie Kovsky Cc: rusty, keescook, kys, haiyangz, sthemmin, linux-kernel, kernel-hardening +++ Eddie Kovsky [17/02/17 22:58 -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. It would be helpful to explain in the changelog the motivation or reason we're adding to the current api, and why this is needed. >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; >+} >+ There needs to be a corresponding !CONFIG_MODULES stub for is_module_ro_address() as well, see is_module_address(), etc. > 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. s/is_module_text_ro_address/is_module_ro_address/ Although I would slightly prefer the name is_module_rodata_address, or something similar, because it's unclear to me (without looking at the code) whether the function covers text addresses. And we already have is_module_text_address() for that case. >+ * >+ */ >+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. Maybe we should be more specific in the comment and clarify that we're getting the module whose rodata/ro_after_init sections contain the given 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 a ro_after_init address gets passed in here, mod will be prematurely set to NULL here, because it is not within [base, base + ro_size). See comment above frob_text() in module.c for a module layout "diagram". Also, starting from layout.base will give us the text region as well, but we just want to check the rodata/ro_after_init regions, same as what the kernel counterpart in patch 2/3 does. The rodata region starts at base + text_size. So we can just simplify this to just one conditional: (ugly, but shouldn't look bad when cleaned up with some variables) if (!within(addr, mod->init_layout.base + mod->init_layout.text_size, mod->init_layout.ro_after_init_size - mod->init_layout.text_size) && !within(addr, mod->core_layout.base + mod->core_layout.text_size, mod->core_layout.ro_after_init_size - mod->core_layout.text_size)) This is because range [base + text_size, base + ro_after_init_size) encompasses both the rodata and ro_after_init regions. Jessica >+ 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] extable: verify address is read-only 2017-02-18 5:58 [PATCH v2 0/3] provide check for ro_after_init memory sections Eddie Kovsky 2017-02-18 5:58 ` [PATCH v2 1/3] module: verify address is read-only Eddie Kovsky @ 2017-02-18 5:58 ` Eddie Kovsky 2017-02-18 6:33 ` kbuild test robot 2017-02-18 6:49 ` kbuild test robot 2017-02-18 5:58 ` [PATCH v2 3/3] Make vmbus register arguments read-only Eddie Kovsky 2 siblings, 2 replies; 12+ messages in thread From: Eddie Kovsky @ 2017-02-18 5:58 UTC (permalink / raw) To: jeyu, rusty, keescook, kys, haiyangz, sthemmin Cc: linux-kernel, kernel-hardening Provide a mechanism to check if the address of a variable is const or ro_after_init. It mimics the existing functions that test if an address is inside the kernel's text section. Signed-off-by: Eddie Kovsky <ewk@edkovsky.org> --- include/linux/kernel.h | 2 ++ kernel/extable.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 4c26dc3a8295..51beea39e6c4 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -444,6 +444,8 @@ extern int core_kernel_data(unsigned long addr); extern int __kernel_text_address(unsigned long addr); extern int kernel_text_address(unsigned long addr); extern int func_ptr_is_kernel_text(void *ptr); +extern int core_kernel_ro_data(unsigned long addr); +extern int kernel_ro_address(unsigned long addr); unsigned long int_sqrt(unsigned long); diff --git a/kernel/extable.c b/kernel/extable.c index 6b0d09051efb..e9608f129730 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -149,3 +149,32 @@ int func_ptr_is_kernel_text(void *ptr) return 1; return is_module_text_address(addr); } + +/** + * core_kernel_ro_data - Verify address points to read-only section + * @addr: address to test + * + */ +int core_kernel_ro_data(unsigned long addr) +{ + if (addr >= (unsigned long)__start_rodata && + addr < (unsigned long)__end_rodata) + return 1; + + if (addr >= (unsigned long)__start_data_ro_after_init && + addr < (unsigned long)__end_data_ro_after_init) + return 1; + + return 0; +} + +/* Verify that address is const or ro_after_init. */ +int kernel_ro_address(unsigned long addr) +{ + if (core_kernel_ro_data(addr)) + return 1; + if (is_module_ro_address(addr)) + return 1; + + return 0; +} -- 2.11.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] extable: verify address is read-only 2017-02-18 5:58 ` [PATCH v2 2/3] extable: " Eddie Kovsky @ 2017-02-18 6:33 ` kbuild test robot 2017-02-18 6:49 ` kbuild test robot 1 sibling, 0 replies; 12+ messages in thread From: kbuild test robot @ 2017-02-18 6:33 UTC (permalink / raw) To: Eddie Kovsky Cc: kbuild-all, jeyu, rusty, keescook, kys, haiyangz, sthemmin, linux-kernel, kernel-hardening [-- Attachment #1: Type: text/plain, Size: 1331 bytes --] Hi Eddie, [auto build test ERROR on linus/master] [also build test ERROR on v4.10-rc8 next-20170217] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Eddie-Kovsky/provide-check-for-ro_after_init-memory-sections/20170218-141040 config: i386-tinyconfig (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): kernel/extable.c: In function 'kernel_ro_address': >> kernel/extable.c:168:6: error: implicit declaration of function 'is_module_ro_address' [-Werror=implicit-function-declaration] if (is_module_ro_address(addr)) ^~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +/is_module_ro_address +168 kernel/extable.c 162 163 /* Verify that address is const or ro_after_init. */ 164 int kernel_ro_address(unsigned long addr) 165 { 166 if (core_kernel_ro_data(addr)) 167 return 1; > 168 if (is_module_ro_address(addr)) 169 return 1; 170 171 return 0; --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 6397 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] extable: verify address is read-only 2017-02-18 5:58 ` [PATCH v2 2/3] extable: " Eddie Kovsky 2017-02-18 6:33 ` kbuild test robot @ 2017-02-18 6:49 ` kbuild test robot 1 sibling, 0 replies; 12+ messages in thread From: kbuild test robot @ 2017-02-18 6:49 UTC (permalink / raw) To: Eddie Kovsky Cc: kbuild-all, jeyu, rusty, keescook, kys, haiyangz, sthemmin, linux-kernel, kernel-hardening [-- Attachment #1: Type: text/plain, Size: 6680 bytes --] Hi Eddie, [auto build test WARNING on linus/master] [also build test WARNING on v4.10-rc8 next-20170217] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Eddie-Kovsky/provide-check-for-ro_after_init-memory-sections/20170218-141040 config: x86_64-randconfig-x008-201707 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): In file included from include/linux/trace_clock.h:12:0, from include/linux/ftrace.h:9, from kernel/extable.c:18: kernel/extable.c: In function 'kernel_ro_address': kernel/extable.c:168:6: error: implicit declaration of function 'is_module_ro_address' [-Werror=implicit-function-declaration] if (is_module_ro_address(addr)) ^ include/linux/compiler.h:149:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/extable.c:168:2: note: in expansion of macro 'if' if (is_module_ro_address(addr)) ^~ cc1: some warnings being treated as errors vim +/if +168 kernel/extable.c 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ > 18 #include <linux/ftrace.h> 19 #include <linux/memory.h> 20 #include <linux/module.h> 21 #include <linux/mutex.h> 22 #include <linux/init.h> 23 24 #include <asm/sections.h> 25 #include <linux/uaccess.h> 26 27 /* 28 * mutex protecting text section modification (dynamic code patching). 29 * some users need to sleep (allocating memory...) while they hold this lock. 30 * 31 * NOT exported to modules - patching kernel text is a really delicate matter. 32 */ 33 DEFINE_MUTEX(text_mutex); 34 35 extern struct exception_table_entry __start___ex_table[]; 36 extern struct exception_table_entry __stop___ex_table[]; 37 38 /* Cleared by build time tools if the table is already sorted. */ 39 u32 __initdata __visible main_extable_sort_needed = 1; 40 41 /* Sort the kernel's built-in exception table */ 42 void __init sort_main_extable(void) 43 { 44 if (main_extable_sort_needed && __stop___ex_table > __start___ex_table) { 45 pr_notice("Sorting __ex_table...\n"); 46 sort_extable(__start___ex_table, __stop___ex_table); 47 } 48 } 49 50 /* Given an address, look for it in the exception tables. */ 51 const struct exception_table_entry *search_exception_tables(unsigned long addr) 52 { 53 const struct exception_table_entry *e; 54 55 e = search_extable(__start___ex_table, __stop___ex_table-1, addr); 56 if (!e) 57 e = search_module_extables(addr); 58 return e; 59 } 60 61 static inline int init_kernel_text(unsigned long addr) 62 { 63 if (addr >= (unsigned long)_sinittext && 64 addr < (unsigned long)_einittext) 65 return 1; 66 return 0; 67 } 68 69 int core_kernel_text(unsigned long addr) 70 { 71 if (addr >= (unsigned long)_stext && 72 addr < (unsigned long)_etext) 73 return 1; 74 75 if (system_state == SYSTEM_BOOTING && 76 init_kernel_text(addr)) 77 return 1; 78 return 0; 79 } 80 81 /** 82 * core_kernel_data - tell if addr points to kernel data 83 * @addr: address to test 84 * 85 * Returns true if @addr passed in is from the core kernel data 86 * section. 87 * 88 * Note: On some archs it may return true for core RODATA, and false 89 * for others. But will always be true for core RW data. 90 */ 91 int core_kernel_data(unsigned long addr) 92 { 93 if (addr >= (unsigned long)_sdata && 94 addr < (unsigned long)_edata) 95 return 1; 96 return 0; 97 } 98 99 int __kernel_text_address(unsigned long addr) 100 { 101 if (core_kernel_text(addr)) 102 return 1; 103 if (is_module_text_address(addr)) 104 return 1; 105 if (is_ftrace_trampoline(addr)) 106 return 1; 107 /* 108 * There might be init symbols in saved stacktraces. 109 * Give those symbols a chance to be printed in 110 * backtraces (such as lockdep traces). 111 * 112 * Since we are after the module-symbols check, there's 113 * no danger of address overlap: 114 */ 115 if (init_kernel_text(addr)) 116 return 1; 117 return 0; 118 } 119 120 int kernel_text_address(unsigned long addr) 121 { 122 if (core_kernel_text(addr)) 123 return 1; 124 if (is_module_text_address(addr)) 125 return 1; 126 return is_ftrace_trampoline(addr); 127 } 128 129 /* 130 * On some architectures (PPC64, IA64) function pointers 131 * are actually only tokens to some data that then holds the 132 * real function address. As a result, to find if a function 133 * pointer is part of the kernel text, we need to do some 134 * special dereferencing first. 135 */ 136 int func_ptr_is_kernel_text(void *ptr) 137 { 138 unsigned long addr; 139 addr = (unsigned long) dereference_function_descriptor(ptr); 140 if (core_kernel_text(addr)) 141 return 1; 142 return is_module_text_address(addr); 143 } 144 145 /** 146 * core_kernel_ro_data - Verify address points to read-only section 147 * @addr: address to test 148 * 149 */ 150 int core_kernel_ro_data(unsigned long addr) 151 { 152 if (addr >= (unsigned long)__start_rodata && 153 addr < (unsigned long)__end_rodata) 154 return 1; 155 156 if (addr >= (unsigned long)__start_data_ro_after_init && 157 addr < (unsigned long)__end_data_ro_after_init) 158 return 1; 159 160 return 0; 161 } 162 163 /* Verify that address is const or ro_after_init. */ 164 int kernel_ro_address(unsigned long addr) 165 { 166 if (core_kernel_ro_data(addr)) 167 return 1; > 168 if (is_module_ro_address(addr)) 169 return 1; 170 171 return 0; --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 31238 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] Make vmbus register arguments read-only 2017-02-18 5:58 [PATCH v2 0/3] provide check for ro_after_init memory sections Eddie Kovsky 2017-02-18 5:58 ` [PATCH v2 1/3] module: verify address is read-only Eddie Kovsky 2017-02-18 5:58 ` [PATCH v2 2/3] extable: " Eddie Kovsky @ 2017-02-18 5:58 ` Eddie Kovsky 2017-02-18 6:30 ` kbuild test robot 2017-02-18 8:55 ` kbuild test robot 2 siblings, 2 replies; 12+ messages in thread From: Eddie Kovsky @ 2017-02-18 5:58 UTC (permalink / raw) To: jeyu, rusty, keescook, kys, haiyangz, sthemmin Cc: linux-kernel, kernel-hardening Use the new RO check functions introduced in this series to make the vmbus register functions verify that the address of their arguments are read-only. Addresses that fail the verification are rejected. Signed-off-by: Eddie Kovsky <ewk@edkovsky.org> --- drivers/hv/vmbus_drv.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index c1b27026f744..e527454ffa59 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1026,6 +1026,11 @@ int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, c if (ret < 0) return ret; + ret = kernel_ro_address(&hv_driver); + if (ret < 1) + pr_err("Module address is not read-only."); + return ret; + hv_driver->driver.name = hv_driver->name; hv_driver->driver.owner = owner; hv_driver->driver.mod_name = mod_name; @@ -1092,6 +1097,11 @@ int vmbus_device_register(struct hv_device *child_device_obj) { int ret = 0; + ret = kernel_ro_address(&child_device_obj); + if (ret < 1) + pr_err("Device address is not read-only."); + return ret; + dev_set_name(&child_device_obj->device, "%pUl", child_device_obj->channel->offermsg.offer.if_instance.b); -- 2.11.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] Make vmbus register arguments read-only 2017-02-18 5:58 ` [PATCH v2 3/3] Make vmbus register arguments read-only Eddie Kovsky @ 2017-02-18 6:30 ` kbuild test robot 2017-02-18 8:55 ` kbuild test robot 1 sibling, 0 replies; 12+ messages in thread From: kbuild test robot @ 2017-02-18 6:30 UTC (permalink / raw) To: Eddie Kovsky Cc: kbuild-all, jeyu, rusty, keescook, kys, haiyangz, sthemmin, linux-kernel, kernel-hardening [-- Attachment #1: Type: text/plain, Size: 2944 bytes --] Hi Eddie, [auto build test WARNING on linus/master] [also build test WARNING on v4.10-rc8 next-20170217] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Eddie-Kovsky/provide-check-for-ro_after_init-memory-sections/20170218-141040 config: i386-randconfig-x007-201707 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): drivers/hv/vmbus_drv.c: In function '__vmbus_driver_register': >> drivers/hv/vmbus_drv.c:1056:26: warning: passing argument 1 of 'kernel_ro_address' makes integer from pointer without a cast [-Wint-conversion] ret = kernel_ro_address(&hv_driver); ^ In file included from include/linux/list.h:8:0, from include/linux/module.h:9, from drivers/hv/vmbus_drv.c:26: include/linux/kernel.h:446:12: note: expected 'long unsigned int' but argument is of type 'struct hv_driver **' extern int kernel_ro_address(unsigned long addr); ^~~~~~~~~~~~~~~~~ drivers/hv/vmbus_drv.c: In function 'vmbus_device_register': drivers/hv/vmbus_drv.c:1127:26: warning: passing argument 1 of 'kernel_ro_address' makes integer from pointer without a cast [-Wint-conversion] ret = kernel_ro_address(&child_device_obj); ^ In file included from include/linux/list.h:8:0, from include/linux/module.h:9, from drivers/hv/vmbus_drv.c:26: include/linux/kernel.h:446:12: note: expected 'long unsigned int' but argument is of type 'struct hv_device **' extern int kernel_ro_address(unsigned long addr); ^~~~~~~~~~~~~~~~~ vim +/kernel_ro_address +1056 drivers/hv/vmbus_drv.c 1040 * 1041 * Registers the given driver with Linux through the 'driver_register()' call 1042 * and sets up the hyper-v vmbus handling for this driver. 1043 * It will return the state of the 'driver_register()' call. 1044 * 1045 */ 1046 int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, const char *mod_name) 1047 { 1048 int ret; 1049 1050 pr_info("registering driver %s\n", hv_driver->name); 1051 1052 ret = vmbus_exists(); 1053 if (ret < 0) 1054 return ret; 1055 > 1056 ret = kernel_ro_address(&hv_driver); 1057 if (ret < 1) 1058 pr_err("Module address is not read-only."); 1059 return ret; 1060 1061 hv_driver->driver.name = hv_driver->name; 1062 hv_driver->driver.owner = owner; 1063 hv_driver->driver.mod_name = mod_name; 1064 hv_driver->driver.bus = &hv_bus; --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 25048 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] Make vmbus register arguments read-only 2017-02-18 5:58 ` [PATCH v2 3/3] Make vmbus register arguments read-only Eddie Kovsky 2017-02-18 6:30 ` kbuild test robot @ 2017-02-18 8:55 ` kbuild test robot 1 sibling, 0 replies; 12+ messages in thread From: kbuild test robot @ 2017-02-18 8:55 UTC (permalink / raw) To: Eddie Kovsky Cc: kbuild-all, jeyu, rusty, keescook, kys, haiyangz, sthemmin, linux-kernel, kernel-hardening [-- Attachment #1: Type: text/plain, Size: 778 bytes --] Hi Eddie, [auto build test ERROR on linus/master] [also build test ERROR on v4.10-rc8 next-20170217] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Eddie-Kovsky/provide-check-for-ro_after_init-memory-sections/20170218-141040 config: x86_64-rhel (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): >> ERROR: "kernel_ro_address" [drivers/hv/hv_vmbus.ko] undefined! --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 38264 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-02-26 17:42 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-02-18 5:58 [PATCH v2 0/3] provide check for ro_after_init memory sections Eddie Kovsky 2017-02-18 5:58 ` [PATCH v2 1/3] module: verify address is read-only Eddie Kovsky 2017-02-20 17:14 ` Stephen Hemminger 2017-02-21 20:32 ` Kees Cook 2017-02-21 20:51 ` Stephen Hemminger 2017-02-26 17:42 ` Jessica Yu 2017-02-18 5:58 ` [PATCH v2 2/3] extable: " Eddie Kovsky 2017-02-18 6:33 ` kbuild test robot 2017-02-18 6:49 ` kbuild test robot 2017-02-18 5:58 ` [PATCH v2 3/3] Make vmbus register arguments read-only Eddie Kovsky 2017-02-18 6:30 ` kbuild test robot 2017-02-18 8:55 ` kbuild test robot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox