This allows to report the current state of the PTI protection and to
enable or disable it for the current task.

Signed-off-by: Willy Tarreau <[email protected]>
---
 arch/x86/include/uapi/asm/prctl.h |  3 +++
 arch/x86/kernel/process_64.c      | 24 ++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/arch/x86/include/uapi/asm/prctl.h 
b/arch/x86/include/uapi/asm/prctl.h
index 5a6aac9..1f1b5bc 100644
--- a/arch/x86/include/uapi/asm/prctl.h
+++ b/arch/x86/include/uapi/asm/prctl.h
@@ -10,6 +10,9 @@
 #define ARCH_GET_CPUID         0x1011
 #define ARCH_SET_CPUID         0x1012
 
+#define ARCH_GET_NOPTI         0x1021
+#define ARCH_SET_NOPTI         0x1022
+
 #define ARCH_MAP_VDSO_X32      0x2001
 #define ARCH_MAP_VDSO_32       0x2002
 #define ARCH_MAP_VDSO_64       0x2003
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index c754662..1686d3d 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -654,6 +654,30 @@ long do_arch_prctl_64(struct task_struct *task, int 
option, unsigned long arg2)
                ret = put_user(base, (unsigned long __user *)arg2);
                break;
        }
+       case ARCH_GET_NOPTI: {
+               unsigned long flag;
+
+               printk(KERN_DEBUG "get1: task=%p ti=%p fl=%16lx\n", task, 
task_thread_info(task), task_thread_info(task)->flags);
+               flag = !!(task_thread_info(task)->flags & _TIF_NOPTI);
+               ret = put_user(flag, (unsigned long __user *)arg2);
+               break;
+       }
+
+       case ARCH_SET_NOPTI:
+               if (!capable(CAP_SYS_RAWIO))
+                       return -EPERM;
+
+               printk(KERN_DEBUG "set1: task=%p ti=%p fl=%16lx doit=%d 
arg2=%ld\n", task, task_thread_info(task), task_thread_info(task)->flags, doit, 
arg2);
+
+               if (doit) {
+                       if (arg2)
+                               task_thread_info(task)->flags |= _TIF_NOPTI;
+                       else
+                               task_thread_info(task)->flags &= ~_TIF_NOPTI;
+
+                       printk(KERN_DEBUG "set2: task=%p ti=%p fl=%16lx\n", 
task, task_thread_info(task), task_thread_info(task)->flags);
+               }
+               break;
 
 #ifdef CONFIG_CHECKPOINT_RESTORE
 # ifdef CONFIG_X86_X32_ABI
-- 
1.7.12.1

Reply via email to