[LTP] [PATCH v6 ltp] Add Intel umip(User Mode Instruction Prevention) basic function tests

Pengfei Xu pengfei.xu@intel.com
Thu Jan 17 15:08:46 CET 2019


Please ignore this commit, will resend again.

On 2019-01-17 at 22:05:13 +0800, Pengfei Xu wrote:
>   umip is a security feature present in new Intel Processors.
>   Intel CPU like ICE lake or newer is required.
>   When umip enabled, it prevents the execution of certain instructions
>   and situation as below:
>     when Current Privilege Level (CPL) is greater than 0, user space
>     applications could not access to system-wide settings such as
>     the global and local descriptor tables, the segment selectors to
>     the current task state and the local descriptor table.
>   umip is enabled by default at boot.
>   umip will protect below instructions in user mode:
>     * SGDT - Store Global Descriptor Table
>     * SIDT - Store Interrupt Descriptor Table
>     * SLDT - Store Local Descriptor Table
>     * SMSW - Store Machine Status Word
>     * STR  - Store Task Register
>   If CPU not support umip, you still could comment cpuinfo check code
>   to verify anyway.
> 
> Signed-off-by: Pengfei Xu <pengfei.xu@intel.com>
> ---
>  runtest/secure_umip                           |   2 +
>  testcases/kernel/security/umip/.gitignore     |   1 +
>  testcases/kernel/security/umip/Makefile       |   7 +
>  testcases/kernel/security/umip/umip_gp_test.c | 182 ++++++++++++++++++++++++++
>  4 files changed, 192 insertions(+)
>  create mode 100644 runtest/secure_umip
>  create mode 100644 testcases/kernel/security/umip/.gitignore
>  create mode 100644 testcases/kernel/security/umip/Makefile
>  create mode 100644 testcases/kernel/security/umip/umip_gp_test.c
> 
> diff --git a/runtest/secure_umip b/runtest/secure_umip
> new file mode 100644
> index 000000000..4082bc2a3
> --- /dev/null
> +++ b/runtest/secure_umip
> @@ -0,0 +1,2 @@
> +#DESCRIPTION: CPU security feature UMIP test
> +umip_instruction_test umip_gp_test
> diff --git a/testcases/kernel/security/umip/.gitignore b/testcases/kernel/security/umip/.gitignore
> new file mode 100644
> index 000000000..9e7022c59
> --- /dev/null
> +++ b/testcases/kernel/security/umip/.gitignore
> @@ -0,0 +1 @@
> +umip_gp_test
> diff --git a/testcases/kernel/security/umip/Makefile b/testcases/kernel/security/umip/Makefile
> new file mode 100644
> index 000000000..18896b6f2
> --- /dev/null
> +++ b/testcases/kernel/security/umip/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +
> +top_srcdir		?= ../../../..
> +
> +include $(top_srcdir)/include/mk/testcases.mk
> +
> +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> diff --git a/testcases/kernel/security/umip/umip_gp_test.c b/testcases/kernel/security/umip/umip_gp_test.c
> new file mode 100644
> index 000000000..b5835d371
> --- /dev/null
> +++ b/testcases/kernel/security/umip/umip_gp_test.c
> @@ -0,0 +1,182 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +/*
> + * testcases/security/umip/umip_gp_test.c
> + * Copyright (C) 2018 Intel Corporation
> + * Author: Neri, Ricardo <ricardo.neri@intel.com>
> + *	 Pengfei, Xu   <pengfei.xu@intel.com>
> + */
> +
> +/*
> + * This test will check if Intel umip(User-Mode Execution Prevention) is
> + * working.
> + *
> + * Intel CPU of ICE lake or newer is required for the test
> + * kconfig requirement:CONFIG_X86_INTEL_UMIP=y
> + *
> + */
> +
> +#define _GNU_SOURCE
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/wait.h>
> +#include <signal.h>
> +
> +#include "tst_test.h"
> +#include "tst_safe_stdio.h"
> +
> +#define CPUINFO_FILE "/proc/cpuinfo"
> +
> +#define GDT_LEN 10
> +#define IDT_LEN 10
> +
> +static int fd = -1;
> +
> +static struct tcase {
> +	enum {
> +	sgdt,
> +	sidt,
> +	sldt,
> +	smsw,
> +	str
> +	} option;
> +	int exp_sig;
> +} tcases[] = {
> +	{sgdt, SIGSEGV},
> +	{sidt, SIGSEGV},
> +	{sldt, SIGSEGV},
> +	{smsw, SIGSEGV},
> +	{str, SIGSEGV},
> +};
> +
> +static void asm_sgdt(void)
> +{
> +	unsigned char val[GDT_LEN];
> +
> +	memset(val, 0, sizeof(val));
> +	tst_res(TINFO, "TEST sgdt, sgdt result save at [%p]", val);
> +	asm volatile("sgdt %0\n" : "=m" (val));
> +	exit(0);
> +}
> +
> +static void asm_sidt(void)
> +{
> +	unsigned char val[IDT_LEN];
> +
> +	memset(val, 0, sizeof(val));
> +	tst_res(TINFO, "TEST sidt, sidt result save at [%p]\n", val);
> +	asm volatile("sidt %0\n" : "=m" (val));
> +	exit(0);
> +}
> +
> +static void asm_sldt(void)
> +{
> +	unsigned long val;
> +
> +	tst_res(TINFO, "TEST sldt, sldt result save at [%p]\n", &val);
> +	asm volatile("sldt %0\n" : "=m" (val));
> +	exit(0);
> +}
> +
> +static void asm_smsw(void)
> +{
> +	unsigned long val;
> +
> +	tst_res(TINFO, "TEST smsw, smsw result save at [%p]\n", &val);
> +	asm volatile("smsw %0\n" : "=m" (val));
> +	exit(0);
> +}
> +
> +static void asm_str(void)
> +{
> +	unsigned long val;
> +
> +	tst_res(TINFO, "TEST str, str result save at [%p]\n", &val);
> +	asm volatile("str %0\n" : "=m" (val));
> +	exit(0);
> +}
> +
> +static void verify_umip_instruction(unsigned int n)
> +{
> +	int status;
> +	struct tcase *tc = &tcases[n];
> +	pid_t pid;
> +
> +	pid = SAFE_FORK();
> +	if (pid == 0) {
> +		switch (tc->option) {
> +		case 0:
> +			asm_sgdt();
> +			break;
> +		case 1:
> +			asm_sidt();
> +			break;
> +		case 2:
> +			asm_sldt();
> +			break;
> +		case 3:
> +			asm_smsw();
> +			break;
> +		case 4:
> +			asm_str();
> +			break;
> +		default:
> +			tst_brk(TCONF, "Invalid tcase parameter:%d",
> +				tc->option);
> +		}
> +		exit(0);
> +	}
> +
> +	SAFE_WAITPID(pid, &status, 0);
> +
> +	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) {
> +		tst_res(TPASS, "Got SIGSEGV");
> +		return;
> +	}
> +	tst_res(TFAIL, "Didn't receive SIGSEGV, child exited with %s",
> +		tst_strstatus(status));
> +}
> +
> +static void setup(void)
> +{
> +	FILE *fp;
> +	int max = 2048;
> +	char buf[max];
> +
> +	// cpuinfo should contain umip
> +	fp = SAFE_FOPEN(CPUINFO_FILE, "r");
> +	while (!feof(fp)) {
> +		if (fgets(buf, sizeof(buf), fp) == NULL) {
> +			tst_brk(TCONF, "cpuinfo show: cpu does not support umip");
> +		}
> +
> +		if (!strstr(buf, "flags"))
> +			continue;
> +
> +		if (strstr(buf, "umip")) {
> +			tst_res(TINFO, "cpuinfo contain umip, cpu support umip");
> +			break;
> +		} else
> +			continue;
> +	}
> +
> +	SAFE_FCLOSE(fp);
> +}
> +
> +static void cleanup(void)
> +{
> +	if (fd != -1)
> +		SAFE_CLOSE(fd);
> +}
> +
> +static struct tst_test test = {
> +	.min_kver = "4.1",
> +	.setup = setup,
> +	.tcnt = ARRAY_SIZE(tcases),
> +	.forks_child = 1,
> +	.test = verify_umip_instruction,
> +	.cleanup = cleanup,
> +	.needs_root = 1,
> +};
> -- 
> 2.14.1
> 


More information about the ltp mailing list