lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Mon, 23 May 2016 14:46:17 +0100
From:	Romeo Cane <romeo.cane@...csson.com>
To:	<linux-kernel@...r.kernel.org>
CC:	Michal Simek <monstr@...str.eu>
Subject: [PATCH] microblaze: fix instruction cache invalidation


Microblaze invalidates the instruction cache via WIC opcode which,
unlike WDC for data cache, requires the virtual address of the target
location when MMU is used. The current code always uses the physical
address, preventing the instruction cache to be properly invalidated
and exposing the risk of user space applications to crash with
signal 4 (illegal instruction) when executing the trampoline code in return
from a signal handler.
Same issue when the code is modified via copy_to_user_page.
This patch fixes the calls to instruction cache invalidation using
the correct addresses.

Signed-off-by: Romeo Cane <romeo.cane@...csson.com>
---
 arch/microblaze/include/asm/cacheflush.h | 6 +++---
 arch/microblaze/kernel/signal.c          | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h
index ffea82a..c978e64 100644
--- a/arch/microblaze/include/asm/cacheflush.h
+++ b/arch/microblaze/include/asm/cacheflush.h
@@ -106,11 +106,11 @@ static inline void copy_to_user_page(struct vm_area_struct *vma,
 				     struct page *page, unsigned long vaddr,
 				     void *dst, void *src, int len)
 {
-	u32 addr = virt_to_phys(dst);
+	u32 paddr = virt_to_phys(dst);
 	memcpy(dst, src, len);
 	if (vma->vm_flags & VM_EXEC) {
-		invalidate_icache_range(addr, addr + PAGE_SIZE);
-		flush_dcache_range(addr, addr + PAGE_SIZE);
+		invalidate_icache_range(vaddr, vaddr + PAGE_SIZE);
+		flush_dcache_range(paddr, paddr + PAGE_SIZE);
 	}
 }

diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 9700152..757dd40 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -200,6 +200,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 					address), address);

 	preempt_disable();
+	invalidate_icache_range(address, address + 8);
 	ptep = pte_offset_map(pmdp, address);
 	if (pte_present(*ptep)) {
 		address = (unsigned long) page_address(pte_page(*ptep));
@@ -207,7 +208,6 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 		address += ((unsigned long)frame->tramp) & ~PAGE_MASK;
 		/* MS address is virtual */
 		address = __virt_to_phys(address);
-		invalidate_icache_range(address, address + 8);
 		flush_dcache_range(address, address + 8);
 	}
 	pte_unmap(ptep);
-- 
1.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ