Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1497286620-15027-9-git-send-email-s.mesoraca16@gmail.com>
Date: Mon, 12 Jun 2017 18:56:57 +0200
From: Salvatore Mesoraca <s.mesoraca16@...il.com>
To: linux-kernel@...r.kernel.org
Cc: linux-security-module@...r.kernel.org,
	kernel-hardening@...ts.openwall.com,
	Salvatore Mesoraca <s.mesoraca16@...il.com>,
	Brad Spengler <spender@...ecurity.net>,
	PaX Team <pageexec@...email.hu>,
	Casey Schaufler <casey@...aufler-ca.com>,
	Kees Cook <keescook@...omium.org>,
	James Morris <james.l.morris@...cle.com>,
	"Serge E. Hallyn" <serge@...lyn.com>,
	x86@...nel.org,
	Ingo Molnar <mingo@...hat.com>
Subject: [PATCH 08/11] Creation of "pagefault_handler_x86" LSM hook

Creation of a new hook to let LSM modules handle user-space pagefaults on
x86.
It can be used to avoid segfaulting the originating process.
If it's the case it can modify process registers before returning.

Signed-off-by: Salvatore Mesoraca <s.mesoraca16@...il.com>
Cc: x86@...nel.org
Cc: Ingo Molnar <mingo@...hat.com>
---
 arch/x86/mm/fault.c       |  6 ++++++
 include/linux/lsm_hooks.h |  9 +++++++++
 include/linux/security.h  | 11 +++++++++++
 security/security.c       | 11 +++++++++++
 4 files changed, 37 insertions(+)

diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 8ad91a0..b75b81a 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -15,6 +15,7 @@
 #include <linux/prefetch.h>		/* prefetchw			*/
 #include <linux/context_tracking.h>	/* exception_enter(), ...	*/
 #include <linux/uaccess.h>		/* faulthandler_disabled()	*/
+#include <linux/security.h>		/* security_pagefault_handler	*/
 
 #include <asm/cpufeature.h>		/* boot_cpu_has, ...		*/
 #include <asm/traps.h>			/* dotraplinkage, ...		*/
@@ -1358,6 +1359,11 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs)
 			local_irq_enable();
 	}
 
+	if (unlikely(security_pagefault_handler_x86(regs,
+						    error_code,
+						    address)))
+		return;
+
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
 
 	if (error_code & PF_WRITE)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 6934cc5..a42c2f8 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -487,6 +487,11 @@
  *	Check if the requested @vmflags are allowed.
  *	@vmflags contains requested the vmflags.
  *	Return 0 if the operation is allowed to continue.
+ * @pagefault_handler_x86:
+ *	Handle pagefaults on x86.
+ *	@regs contains process' registers.
+ *	@error_code contains error code for the pagefault.
+ *	@address contains the address that caused the pagefault.
  * @file_lock:
  *	Check permission before performing file locking operations.
  *	Note: this hook mediates both flock and fcntl style locks.
@@ -1487,6 +1492,9 @@
 	int (*file_mprotect)(struct vm_area_struct *vma, unsigned long reqprot,
 				unsigned long prot);
 	int (*check_vmflags)(vm_flags_t vmflags);
+	int (*pagefault_handler_x86)(struct pt_regs *regs,
+				     unsigned long error_code,
+				     unsigned long address);
 	int (*file_lock)(struct file *file, unsigned int cmd);
 	int (*file_fcntl)(struct file *file, unsigned int cmd,
 				unsigned long arg);
@@ -1759,6 +1767,7 @@ struct security_hook_heads {
 	struct list_head mmap_file;
 	struct list_head file_mprotect;
 	struct list_head check_vmflags;
+	struct list_head pagefault_handler_x86;
 	struct list_head file_lock;
 	struct list_head file_fcntl;
 	struct list_head file_set_fowner;
diff --git a/include/linux/security.h b/include/linux/security.h
index 67e33b6..bc38c83 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -303,6 +303,9 @@ int security_mmap_file(struct file *file, unsigned long prot,
 int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
 			   unsigned long prot);
 int security_check_vmflags(vm_flags_t vmflags);
+int __maybe_unused security_pagefault_handler_x86(struct pt_regs *regs,
+						  unsigned long error_code,
+						  unsigned long address);
 int security_file_lock(struct file *file, unsigned int cmd);
 int security_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg);
 void security_file_set_fowner(struct file *file);
@@ -836,6 +839,14 @@ static inline int security_check_vmflags(vm_flags_t vmflags)
 	return 0;
 }
 
+static inline int __maybe_unused security_pagefault_handler_x86(
+						struct pt_regs *regs,
+						unsigned long error_code,
+						unsigned long address)
+{
+	return 0;
+}
+
 static inline int security_file_lock(struct file *file, unsigned int cmd)
 {
 	return 0;
diff --git a/security/security.c b/security/security.c
index 25d58f0..cf15686 100644
--- a/security/security.c
+++ b/security/security.c
@@ -910,6 +910,17 @@ int security_check_vmflags(vm_flags_t vmflags)
 	return call_int_hook(check_vmflags, 0, vmflags);
 }
 
+int __maybe_unused security_pagefault_handler_x86(struct pt_regs *regs,
+						  unsigned long error_code,
+						  unsigned long address)
+{
+	return call_int_hook(pagefault_handler_x86,
+			     0,
+			     regs,
+			     error_code,
+			     address);
+}
+
 int security_file_lock(struct file *file, unsigned int cmd)
 {
 	return call_int_hook(file_lock, 0, file, cmd);
-- 
1.9.1

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.