[PATCH v4 38/39] x86/shstk: Add ARCH_SHSTK_UNLOCK
From: Rick Edgecombe <rick.p.edgecombe@intel.com>
Date: 2022-12-03 00:44:04
Also in:
linux-arch, linux-doc, linux-mm, lkml
Subsystem:
documentation, the rest, x86 architecture (32-bit and 64-bit) · Maintainers:
Jonathan Corbet, Linus Torvalds, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen
From: Mike Rapoport <redacted> Userspace loaders may lock features before a CRIU restore operation has the chance to set them to whatever state is required by the process being restored. Allow a way for CRIU to unlock features. Add it as an arch_prctl() like the other shadow stack operations, but restrict it being called by the ptrace arch_pctl() interface. Tested-by: Pengfei Xu <redacted> Tested-by: John Allen <john.allen@amd.com> Signed-off-by: Mike Rapoport <redacted> [Merged into recent API changes, added commit log and docs] Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com> --- v4: - Add to docs that it is ptrace only. - Remove "CET" references v3: - Depend on CONFIG_CHECKPOINT_RESTORE (Kees) Documentation/x86/shstk.rst | 4 ++++ arch/x86/include/uapi/asm/prctl.h | 1 + arch/x86/kernel/process_64.c | 1 + arch/x86/kernel/shstk.c | 9 +++++++-- 4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/Documentation/x86/shstk.rst b/Documentation/x86/shstk.rst
index 8e0b2fe83ef8..0d7d1ccfff06 100644
--- a/Documentation/x86/shstk.rst
+++ b/Documentation/x86/shstk.rst@@ -73,6 +73,10 @@ arch_prctl(ARCH_SHSTK_LOCK, unsigned long features) are ignored. The mask is ORed with the existing value. So any feature bits set here cannot be enabled or disabled afterwards. +arch_prctl(ARCH_SHSTK_UNLOCK, unsigned long features) + Unlock features. 'features' is a mask of all features to unlock. All + bits set are processed, unset bits are ignored. Only works via ptrace. + The return values are as following: On success, return 0. On error, errno can be::
diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h
index f13751c6bae4..0c95688cf58e 100644
--- a/arch/x86/include/uapi/asm/prctl.h
+++ b/arch/x86/include/uapi/asm/prctl.h@@ -30,6 +30,7 @@ #define ARCH_SHSTK_ENABLE 0x5001 #define ARCH_SHSTK_DISABLE 0x5002 #define ARCH_SHSTK_LOCK 0x5003 +#define ARCH_SHSTK_UNLOCK 0x5004 /* ARCH_SHSTK_ features bits */ #define ARCH_SHSTK_SHSTK (1ULL << 0)
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 4ddd7d9209e1..2be6e01fb144 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c@@ -921,6 +921,7 @@ long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2) case ARCH_SHSTK_ENABLE: case ARCH_SHSTK_DISABLE: case ARCH_SHSTK_LOCK: + case ARCH_SHSTK_UNLOCK: return shstk_prctl(task, option, arg2); default: ret = -EINVAL;
diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c
index 5d91e653f77a..95579f7bace3 100644
--- a/arch/x86/kernel/shstk.c
+++ b/arch/x86/kernel/shstk.c@@ -455,9 +455,14 @@ long shstk_prctl(struct task_struct *task, int option, unsigned long features) return 0; } - /* Don't allow via ptrace */ - if (task != current) + /* Only allow via ptrace */ + if (task != current) { + if (option == ARCH_SHSTK_UNLOCK && IS_ENABLED(CONFIG_CHECKPOINT_RESTORE)) { + task->thread.features_locked &= ~features; + return 0; + } return -EINVAL; + } /* Do not allow to change locked features */ if (features & task->thread.features_locked)
--
2.17.1