lkml.org 
[lkml]   [2017]   [Jun]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 08/11] Creation of "pagefault_handler_x86" LSM hook
Date
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@gmail.com>
Cc: x86@kernel.org
Cc: Ingo Molnar <mingo@redhat.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
\
 
 \ /
  Last update: 2017-06-12 20:55    [W:1.564 / U:0.016 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site