linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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

* [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

* [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 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

* 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

* 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

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

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

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;
as well as URLs for NNTP newsgroup(s).