From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932170AbcAYLM2 (ORCPT ); Mon, 25 Jan 2016 06:12:28 -0500 Received: from mail.karo-electronics.de ([81.173.242.67]:58110 "EHLO mail.karo-electronics.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755506AbcAYLMY (ORCPT ); Mon, 25 Jan 2016 06:12:24 -0500 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= To: Rusty Russell , linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Subject: [PATCH] module: Fix regression introduced by commit: b0d7290e85a5 "module: clean up RO/NX handling." Date: Mon, 25 Jan 2016 12:11:51 +0100 Message-Id: <1453720311-9594-1-git-send-email-LW@KARO-electronics.de> X-Mailer: git-send-email 2.1.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org commit b0d7290e85a5 ("module: clean up RO/NX handling.") threw away the size checks which were in place before calling the set_memory_*() functions. This produces a kernel bug upon module load with CONFIG_DEBUG_SET_MODULE_RONX=y: kernel BUG at mm/memory.c:1898! Internal error: Oops - BUG: 0 [#1] ARM Modules linked in: CPU: 0 PID: 825 Comm: modprobe Not tainted 4.4.0-next-20160121+ #53 Hardware name: Freescale MXS (Device Tree) task: cef6c380 ti: ce93a000 task.ti: ce93a000 PC is at apply_to_page_range+0x190/0x1bc LR is at change_memory_common+0x74/0xcc pc : [] lr : [] psr: 60000013 sp : ce93be40 ip : bf011000 fp : bf012000 r10: bf012000 r9 : bf0091d4 r8 : ce93be80 r7 : 00000000 r6 : bf012000 r5 : 00000001 r4 : bf012000 r3 : c0011d38 r2 : 00000000 r1 : bf012000 r0 : c0633458 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 0005317f Table: 4ef0c000 DAC: 00000051 Process modprobe (pid: 825, stack limit = 0xce93a190) Stack: (0xce93be40 to 0xce93c000) be40: c0633458 bf012000 00000000 bf012000 00000001 bf012000 00000000 00000080 be60: bf0091d4 ce93bef4 00000000 c0011ce0 ce93be80 00000000 bf0071dc bf0091e4 be80: 00000080 00000000 bf009100 ce93bf48 00000001 bf00910c bf009100 00000000 bea0: bf0091d4 c005d2a0 00000000 cfbd8de0 00000000 00000014 007fb980 00000000 bec0: d0a1d01c bf009250 bf00910c 00000000 d0a19000 b6e4b000 00000f80 755f6f74 bee0: 5f726573 bf007024 00000032 bf0071b4 00000006 00000000 00000000 00000000 bf00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bf20: c005da70 0000306c 00000000 b6e4f06c d0a1d06c ce93a000 007fb980 00000051 bf40: 007fbbd8 c005dae0 d0a0a000 0001306c d0a1c98c d0a13c07 d0a177c8 0000a000 bf60: 0000cbe0 00000000 00000000 00000000 0000002a 0000002b 00000020 00000024 bf80: 00000018 00000000 b6f83228 bec859f8 00000000 00000080 c000a4e4 ce93a000 bfa0: 00000000 c000a340 b6f83228 bec859f8 b6e3c000 0001306c 007fb980 00000000 bfc0: b6f83228 bec859f8 00000000 00000080 007fb980 00000008 00000000 007fbbd8 bfe0: b6f1fa70 bec856c8 0000aab4 b6f1fa80 60000010 b6e3c000 00000000 00000000 [] (apply_to_page_range) from [] (change_memory_common+0x74/0xcc) [] (change_memory_common) from [] (load_module+0x16c8/0x1e3c) [] (load_module) from [] (SyS_init_module+0xcc/0x138) [] (SyS_init_module) from [] (ret_fast_syscall+0x0/0x38) Code: e0834104 eaffffc3 e5191008 eaffffbb (e7f001f2) ---[ end trace fbf287e335e94b28 ]--- This happens because the set_memory_*() functions are eventually being called with a zero parameter and thus apply_to_page_range() in mm/memory.c barfs due to: unsigned long end = addr + size; ... BUG_ON(addr >= end); Reinstate the size checks, as they were before the offending commit. Signed-off-by: Lothar Waßmann --- kernel/module.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index 8358f46..40d8e42 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1863,8 +1863,9 @@ static void frob_text(const struct module_layout *layout, { BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); - set_memory((unsigned long)layout->base, - layout->text_size >> PAGE_SHIFT); + if (layout->text_size) + set_memory((unsigned long)layout->base, + layout->text_size >> PAGE_SHIFT); } static void frob_rodata(const struct module_layout *layout, @@ -1873,8 +1874,9 @@ static void frob_rodata(const struct module_layout *layout, BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); - set_memory((unsigned long)layout->base + layout->text_size, - (layout->ro_size - layout->text_size) >> PAGE_SHIFT); + if (layout->ro_size > layout->text_size) + set_memory((unsigned long)layout->base + layout->text_size, + (layout->ro_size - layout->text_size) >> PAGE_SHIFT); } static void frob_writable_data(const struct module_layout *layout, @@ -1883,8 +1885,9 @@ static void frob_writable_data(const struct module_layout *layout, BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1)); - set_memory((unsigned long)layout->base + layout->ro_size, - (layout->size - layout->ro_size) >> PAGE_SHIFT); + if (layout->size > layout->ro_size) + set_memory((unsigned long)layout->base + layout->ro_size, + (layout->size - layout->ro_size) >> PAGE_SHIFT); } /* livepatching wants to disable read-only so it can frob module. */ -- 2.1.4