From patchwork Thu Jun 7 14:38:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yu-cheng Yu X-Patchwork-Id: 10452345 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BF77E60146 for ; Thu, 7 Jun 2018 14:43:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ABB7D294DF for ; Thu, 7 Jun 2018 14:43:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9EDF329511; Thu, 7 Jun 2018 14:43:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B5699294DF for ; Thu, 7 Jun 2018 14:42:59 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 526736B0299; Thu, 7 Jun 2018 10:42:34 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 4B2576B029F; Thu, 7 Jun 2018 10:42:34 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 262A06B02A1; Thu, 7 Jun 2018 10:42:34 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pg0-f71.google.com (mail-pg0-f71.google.com [74.125.83.71]) by kanga.kvack.org (Postfix) with ESMTP id C50CE6B0299 for ; Thu, 7 Jun 2018 10:42:33 -0400 (EDT) Received: by mail-pg0-f71.google.com with SMTP id e11-v6so3593326pgt.19 for ; Thu, 07 Jun 2018 07:42:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to :subject:date:message-id:in-reply-to:references; bh=SSunv5I7PGu6ThmIPT5HqkLNEgN7YNAqZY3HGYfbg10=; b=ou8he/4xDcfpGN+WOZ8ENm0zE8JJxOrsr+ZIXgNsgmbwDLH1B0u+Pt6NO8zIkk3DlD V/jfyj7GCbgxPNyC9+YwjNOoVwAYEIyjkuHwzmkbCTpxEmnMrGVdGwB4ZnLSYt9Qmraw MCSyC4SV3mrAVZER2SKnpgHgUA0RlhGSgHLVu7Zq2ThEYWK+83eST/QwpZJYZ/svoRLs /oqtt/f4Xm+grVVuXzR602+9QBUmtxq+dad41dPpO9BmzPGAXEalnxH5FVTpvus4sEv/ O7SR4fGPE07mJgyYk0hi0USJ0/XbpeXcUNkbyUC2DQUYWBkOzzObX9J0f9+1OvVmp6x7 TO/Q== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of yu-cheng.yu@intel.com designates 134.134.136.65 as permitted sender) smtp.mailfrom=yu-cheng.yu@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: APt69E1x68eiV9A99H57X1dLVbUik7zPzPP9Q9ELrTn9IeL3hIz8FOAJ nYjpXRbBzhz8/kcFgXp1ghVshyg3Z8cwU3XmNN/TWiqBnq1UlGDnW/VdoUo4M/YTM+s910V3hbz YEk9e8b7m56At+Xwhr+sAdu5rN0eWT7ZMCJujsmOY00YOieetTgySA/mDc2Dez9APIw== X-Received: by 2002:a63:6584:: with SMTP id z126-v6mr1842176pgb.168.1528382553439; Thu, 07 Jun 2018 07:42:33 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLn8/z5BxnDaGrTWmV3M9K0fixD6AfwyA82+FFzUPttu1vn8nT8w0cb9oNfx8RKDazQCj3W X-Received: by 2002:a63:6584:: with SMTP id z126-v6mr1842077pgb.168.1528382551554; Thu, 07 Jun 2018 07:42:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528382551; cv=none; d=google.com; s=arc-20160816; b=zG2xiNgj/LdzEdAN0u+R8pKRxbyikYr7nvmhYzf+xIYdU+dQNWJMF9D1UcLnbmXDto CkEpdrv1Gu4sxWsnykAhcYJAqPiFmPnoiNKgS33pCKfFfeZVJ3Cr6lC+2Ukr7q2H3IST z65nx9mfoYtNALMD+TPRfIkQcRHUxXGQRh8nUPt9Y913B/WnjoCvTyZI/fCWtPLVeLg7 1kpHytOeXcfLiD/VMZDoCahUJzhwEK+Qs3VrCmzDt0ovKMAos5FgqJsCWbo9rh3GxQrJ 4E31KC0oyuVq8cQVPNuXct93tZ9hqUlN8tPsRW8jIzJxhtWOhuTOaB9TCTyAS7kP25Ga qJMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :arc-authentication-results; bh=SSunv5I7PGu6ThmIPT5HqkLNEgN7YNAqZY3HGYfbg10=; b=L6kfUalLW69LDYVD8gxW2eUhyJegQuslT9s8wkcu5mDCqxICFZHl2vay52bdujhf/y m9lOT9DoXzof4wXhUcbfn3h6yStIBGVCo49cln7YfqXQ/43aSlO1S+hNHs0vJMu8/e9c KgkyqTKkOf8HikRVIOA2SRQT//8/3RoWMipI1td4EfGOxpbekzJCkcGrUBJ5i+qzf+qW GmGlLJ98JaUPO2FB9KQrcpZtZeoxvTpknnBHN5s7vZgHg7/nRE30ZexV1rFkJ9M4J2Pm NMx3w8Yfo/dkQoMYEc2a6qaq3N4eGTfpkDd+6Aq4hB299klWhoO+NmTIkBrBojCV812J 0JIA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of yu-cheng.yu@intel.com designates 134.134.136.65 as permitted sender) smtp.mailfrom=yu-cheng.yu@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga03.intel.com (mga03.intel.com. [134.134.136.65]) by mx.google.com with ESMTPS id z141-v6si21943489pfc.95.2018.06.07.07.42.31 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Jun 2018 07:42:31 -0700 (PDT) Received-SPF: pass (google.com: domain of yu-cheng.yu@intel.com designates 134.134.136.65 as permitted sender) client-ip=134.134.136.65; Authentication-Results: mx.google.com; spf=pass (google.com: domain of yu-cheng.yu@intel.com designates 134.134.136.65 as permitted sender) smtp.mailfrom=yu-cheng.yu@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Jun 2018 07:42:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,486,1520924400"; d="scan'208";a="235505954" Received: from 2b52.sc.intel.com ([143.183.136.51]) by fmsmga006.fm.intel.com with ESMTP; 07 Jun 2018 07:42:30 -0700 From: Yu-cheng Yu To: linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, x86@kernel.org, "H. Peter Anvin" , Thomas Gleixner , Ingo Molnar , "H.J. Lu" , Vedvyas Shanbhogue , "Ravi V. Shankar" , Dave Hansen , Andy Lutomirski , Jonathan Corbet , Oleg Nesterov , Arnd Bergmann , Mike Kravetz Subject: [PATCH 6/7] tools: Add cetcmd Date: Thu, 7 Jun 2018 07:38:54 -0700 Message-Id: <20180607143855.3681-7-yu-cheng.yu@intel.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180607143855.3681-1-yu-cheng.yu@intel.com> References: <20180607143855.3681-1-yu-cheng.yu@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP From: "H.J. Lu" Introduce CET command-line utility. This utility allows system admin to enable/disable CET features and set default shadow stack size. Signed-off-by: H.J. Lu --- tools/Makefile | 13 +-- tools/arch/x86/include/uapi/asm/elf_property.h | 16 +++ tools/arch/x86/include/uapi/asm/prctl.h | 33 ++++++ tools/cet/.gitignore | 1 + tools/cet/Makefile | 11 ++ tools/cet/cetcmd.c | 134 +++++++++++++++++++++++++ tools/include/uapi/asm/elf_property.h | 4 + tools/include/uapi/asm/prctl.h | 4 + 8 files changed, 210 insertions(+), 6 deletions(-) create mode 100644 tools/arch/x86/include/uapi/asm/elf_property.h create mode 100644 tools/arch/x86/include/uapi/asm/prctl.h create mode 100644 tools/cet/.gitignore create mode 100644 tools/cet/Makefile create mode 100644 tools/cet/cetcmd.c create mode 100644 tools/include/uapi/asm/elf_property.h create mode 100644 tools/include/uapi/asm/prctl.h diff --git a/tools/Makefile b/tools/Makefile index be02c8b904db..bdca71e61d22 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -10,6 +10,7 @@ help: @echo 'Possible targets:' @echo '' @echo ' acpi - ACPI tools' + @echo ' cet - Intel CET tools' @echo ' cgroup - cgroup tools' @echo ' cpupower - a tool for all things x86 CPU power' @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' @@ -59,7 +60,7 @@ acpi: FORCE cpupower: FORCE $(call descend,power/$@) -cgroup firewire hv guest spi usb virtio vm bpf iio gpio objtool leds wmi: FORCE +cet cgroup firewire hv guest spi usb virtio vm bpf iio gpio objtool leds wmi: FORCE $(call descend,$@) liblockdep: FORCE @@ -91,7 +92,7 @@ freefall: FORCE kvm_stat: FORCE $(call descend,kvm/$@) -all: acpi cgroup cpupower gpio hv firewire liblockdep \ +all: acpi cet cgroup cpupower gpio hv firewire liblockdep \ perf selftests spi turbostat usb \ virtio vm bpf x86_energy_perf_policy \ tmon freefall iio objtool kvm_stat wmi @@ -102,7 +103,7 @@ acpi_install: cpupower_install: $(call descend,power/$(@:_install=),install) -cgroup_install firewire_install gpio_install hv_install iio_install perf_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install: +cet_install cgroup_install firewire_install gpio_install hv_install iio_install perf_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install: $(call descend,$(@:_install=),install) liblockdep_install: @@ -123,7 +124,7 @@ freefall_install: kvm_stat_install: $(call descend,kvm/$(@:_install=),install) -install: acpi_install cgroup_install cpupower_install gpio_install \ +install: acpi_install cet_install cgroup_install cpupower_install gpio_install \ hv_install firewire_install iio_install liblockdep_install \ perf_install selftests_install turbostat_install usb_install \ virtio_install vm_install bpf_install x86_energy_perf_policy_install \ @@ -136,7 +137,7 @@ acpi_clean: cpupower_clean: $(call descend,power/cpupower,clean) -cgroup_clean hv_clean firewire_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean: +cet_clean cgroup_clean hv_clean firewire_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean: $(call descend,$(@:_clean=),clean) liblockdep_clean: @@ -170,7 +171,7 @@ freefall_clean: build_clean: $(call descend,build,clean) -clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \ +clean: acpi_clean cet_clean cgroup_clean cpupower_clean hv_clean firewire_clean \ perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \ diff --git a/tools/arch/x86/include/uapi/asm/elf_property.h b/tools/arch/x86/include/uapi/asm/elf_property.h new file mode 100644 index 000000000000..343a871b8fc1 --- /dev/null +++ b/tools/arch/x86/include/uapi/asm/elf_property.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _UAPI_ASM_X86_ELF_PROPERTY_H +#define _UAPI_ASM_X86_ELF_PROPERTY_H + +/* + * pr_type + */ +#define GNU_PROPERTY_X86_FEATURE_1_AND (0xc0000002) + +/* + * Bits for GNU_PROPERTY_X86_FEATURE_1_AND + */ +#define GNU_PROPERTY_X86_FEATURE_1_SHSTK (0x00000002) +#define GNU_PROPERTY_X86_FEATURE_1_IBT (0x00000001) + +#endif /* _UAPI_ASM_X86_ELF_PROPERTY_H */ diff --git a/tools/arch/x86/include/uapi/asm/prctl.h b/tools/arch/x86/include/uapi/asm/prctl.h new file mode 100644 index 000000000000..fef476d2d2f6 --- /dev/null +++ b/tools/arch/x86/include/uapi/asm/prctl.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _ASM_X86_PRCTL_H +#define _ASM_X86_PRCTL_H + +#define ARCH_SET_GS 0x1001 +#define ARCH_SET_FS 0x1002 +#define ARCH_GET_FS 0x1003 +#define ARCH_GET_GS 0x1004 + +#define ARCH_GET_CPUID 0x1011 +#define ARCH_SET_CPUID 0x1012 + +#define ARCH_MAP_VDSO_X32 0x2001 +#define ARCH_MAP_VDSO_32 0x2002 +#define ARCH_MAP_VDSO_64 0x2003 + +#define ARCH_CET_STATUS 0x3001 +#define ARCH_CET_DISABLE 0x3002 +#define ARCH_CET_LOCK 0x3003 +#define ARCH_CET_EXEC 0x3004 +#define ARCH_CET_ALLOC_SHSTK 0x3005 +#define ARCH_CET_PUSH_SHSTK 0x3006 +#define ARCH_CET_LEGACY_BITMAP 0x3007 + +/* + * Settings for ARCH_CET_EXEC + */ +#define CET_EXEC_ELF_PROPERTY 0 +#define CET_EXEC_ALWAYS_OFF 1 +#define CET_EXEC_ALWAYS_ON 2 +#define CET_EXEC_MAX CET_EXEC_ALWAYS_ON + +#endif /* _ASM_X86_PRCTL_H */ diff --git a/tools/cet/.gitignore b/tools/cet/.gitignore new file mode 100644 index 000000000000..bd100f593454 --- /dev/null +++ b/tools/cet/.gitignore @@ -0,0 +1 @@ +cetcmd diff --git a/tools/cet/Makefile b/tools/cet/Makefile new file mode 100644 index 000000000000..fae42b84d796 --- /dev/null +++ b/tools/cet/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +# Makefile for CET tools + +CFLAGS = -O2 -g -Wall -Wextra -I../include/uapi + +all: cetcmd +%: %.c + $(CC) $(CFLAGS) -o $@ $^ + +clean: + $(RM) cetcmd diff --git a/tools/cet/cetcmd.c b/tools/cet/cetcmd.c new file mode 100644 index 000000000000..dbbfb5267c1f --- /dev/null +++ b/tools/cet/cetcmd.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum command_line_switch { + OPTION_ELF_PROPERTY = 150, + OPTION_ALWAYS_OFF, + OPTION_ALWAYS_ON, + OPTION_SHSTK_SIZE +}; + +static const struct option options[] = { + {"property", no_argument, 0, OPTION_ELF_PROPERTY}, + {"off", no_argument, 0, OPTION_ALWAYS_OFF}, + {"on", no_argument, 0, OPTION_ALWAYS_ON}, + {"shstk-size", required_argument, 0, OPTION_SHSTK_SIZE}, + {"feature", required_argument, 0, 'f'}, + {"help", no_argument, 0, 'h'}, + {0, no_argument, 0, 0} +}; + +__attribute__((__noreturn__)) +static void +usage(FILE *stream, int exit_status) +{ + fprintf(stream, "Usage: %s -- command [args]\n", + program_invocation_short_name); + fprintf(stream, " Run command with CET features\n"); + fprintf(stream, " The options are:\n"); + fprintf(stream, + "\t--property Enable CET features based on ELF property note\n" + "\t--off Always disable CET features\n" + "\t--on Always enable CET features\n" + "\t-f, --feature [ibt|shstk] Control CET [IBT|SHSTK] feature\n" + "\t--shstk-size SIZE Set shadow stack size\n" + "\t-h --help Display this information\n"); + + exit(exit_status); +} + +extern int arch_prctl(int, unsigned long *); + +int +main(int argc, char *const *argv, char *const *envp) +{ + int c; + unsigned long values[3] = {0, -1, 0}; + unsigned long status[3]; + unsigned long shstk_size = -1; + char **args; + size_t i, num_of_args; + + while ((c = getopt_long(argc, argv, "f:h", + options, (int *) 0)) != EOF) { + switch (c) { + case OPTION_ELF_PROPERTY: + values[1] = CET_EXEC_ELF_PROPERTY; + break; + + case OPTION_ALWAYS_OFF: + values[1] = CET_EXEC_ALWAYS_OFF; + break; + + case OPTION_ALWAYS_ON: + values[1] = CET_EXEC_ALWAYS_ON; + break; + + case OPTION_SHSTK_SIZE: + shstk_size = strtol(optarg, NULL, 0); + break; + + case 'f': + if (strcasecmp(optarg, "ibt") == 0) + values[0] = GNU_PROPERTY_X86_FEATURE_1_IBT; + else if (strcasecmp(optarg, "shstk") == 0) + values[0] = GNU_PROPERTY_X86_FEATURE_1_SHSTK; + else + usage(stderr, EXIT_FAILURE); + break; + + case 'h': + usage(stdout, EXIT_SUCCESS); + + default: + usage(stderr, EXIT_FAILURE); + } + } + + if ((optind + 1) > argc || + (values[1] == (unsigned long)-1 && + shstk_size == (unsigned long)-1)) + usage(stderr, EXIT_FAILURE); + + /* If --shstk-size isn't used, get the current shadow stack size. */ + if (shstk_size == (unsigned long)-1) { + if (arch_prctl(ARCH_CET_STATUS, status) < 0) + error(EXIT_FAILURE, errno, "arch_prctl failed\n"); + shstk_size = status[2]; + } + + /* If --property/--off/--on aren't used, clear all features. */ + if (values[1] == (unsigned long)-1) { + values[0] = 0; + values[1] = 0; + } else { + if (values[0] == 0) + values[0] = (GNU_PROPERTY_X86_FEATURE_1_IBT | + GNU_PROPERTY_X86_FEATURE_1_SHSTK); + } + + values[2] = shstk_size; + if (arch_prctl(ARCH_CET_EXEC, values) < 0) + error(EXIT_FAILURE, errno, "arch_prctl failed\n"); + + num_of_args = argc - optind + 1; + args = malloc(num_of_args * sizeof(char *)); + if (args == NULL) + error(EXIT_FAILURE, errno, "malloc failed\n"); + + for (i = 0; i < num_of_args; i++) + args[i] = argv[optind + i]; + args[i] = NULL; + + return execvpe(argv[optind], args, envp); +} diff --git a/tools/include/uapi/asm/elf_property.h b/tools/include/uapi/asm/elf_property.h new file mode 100644 index 000000000000..1281b4e1a578 --- /dev/null +++ b/tools/include/uapi/asm/elf_property.h @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#if defined(__i386__) || defined(__x86_64__) +#include "../../arch/x86/include/uapi/asm/elf_property.h" +#endif \ No newline at end of file diff --git a/tools/include/uapi/asm/prctl.h b/tools/include/uapi/asm/prctl.h new file mode 100644 index 000000000000..b0894b828b06 --- /dev/null +++ b/tools/include/uapi/asm/prctl.h @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#if defined(__i386__) || defined(__x86_64__) +#include "../../arch/x86/include/uapi/asm/prctl.h" +#endif \ No newline at end of file