Re: [RFC PATCH v2 27/27] x86/cet: Add arch_prctl functions for CET
From: Yu-cheng Yu <hidden>
Date: 2018-07-11 20:59:26
Also in:
linux-api, linux-arch, linux-mm, lkml
On Wed, 2018-07-11 at 12:45 -0700, Jann Horn wrote:
On Tue, Jul 10, 2018 at 3:31 PM Yu-cheng Yu [off-list ref] wrote:quoted
arch_prctl(ARCH_CET_STATUS, unsigned long *addr) Return CET feature status. The parameter 'addr' is a pointer to a user buffer. On returning to the caller, the kernel fills the following information: *addr = SHSTK/IBT status *(addr + 1) = SHSTK base address *(addr + 2) = SHSTK size arch_prctl(ARCH_CET_DISABLE, unsigned long features) Disable SHSTK and/or IBT specified in 'features'. Return -EPERM if CET is locked out. arch_prctl(ARCH_CET_LOCK) Lock out CET feature. arch_prctl(ARCH_CET_ALLOC_SHSTK, unsigned long *addr) Allocate a new SHSTK. The parameter 'addr' is a pointer to a user buffer and indicates the desired SHSTK size to allocate. On returning to the caller the buffer contains the address of the new SHSTK. arch_prctl(ARCH_CET_LEGACY_BITMAP, unsigned long *addr) Allocate an IBT legacy code bitmap if the current task does not have one. The parameter 'addr' is a pointer to a user buffer. On returning to the caller, the kernel fills the following information: *addr = IBT bitmap base address *(addr + 1) = IBT bitmap size Signed-off-by: H.J. Lu <redacted> Signed-off-by: Yu-cheng Yu <redacted>[...]quoted
diff --git a/arch/x86/kernel/cet_prctl.cb/arch/x86/kernel/cet_prctl.c new file mode 100644 index 000000000000..86bb78ae656d--- /dev/null +++ b/arch/x86/kernel/cet_prctl.c@@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include <linux/errno.h> +#include <linux/uaccess.h> +#include <linux/prctl.h> +#include <linux/compat.h> +#include <asm/processor.h> +#include <asm/prctl.h> +#include <asm/elf.h> +#include <asm/elf_property.h> +#include <asm/cet.h> + +/* See Documentation/x86/intel_cet.txt. */ + +static int handle_get_status(unsigned long arg2) +{ + unsigned int features = 0; + unsigned long shstk_base, shstk_size; + + if (current->thread.cet.shstk_enabled) + features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; + if (current->thread.cet.ibt_enabled) + features |= GNU_PROPERTY_X86_FEATURE_1_IBT; + + shstk_base = current->thread.cet.shstk_base; + shstk_size = current->thread.cet.shstk_size; + + if (in_ia32_syscall()) { + unsigned int buf[3]; + + buf[0] = features; + buf[1] = (unsigned int)shstk_base; + buf[2] = (unsigned int)shstk_size; + return copy_to_user((unsigned int __user *)arg2,buf, + sizeof(buf)); + } else { + unsigned long buf[3]; + + buf[0] = (unsigned long)features; + buf[1] = shstk_base; + buf[2] = shstk_size; + return copy_to_user((unsigned long __user *)arg2, buf, + sizeof(buf)); + }Other places in the kernel (e.g. the BPF subsystem) just unconditionally use u64 instead of unsigned long to avoid having to switch between different sizes. I wonder whether that would make sense here?
Yes, that simplifies the code. I will make that change. Yu-cheng -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html