Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/compel
diff options
context:
space:
mode:
authorDmitry Safonov <dima@arista.com>2021-02-25 22:57:10 +0300
committerAndrei Vagin <avagin@gmail.com>2021-09-03 20:31:00 +0300
commite2e8be37f22b2fb4623af3bec844cf5a98e823c1 (patch)
treed3012c0a0dd829dc1a17229f7328e5cec4550f18 /compel
parent327e14933d6b2391d0e3d0790e6556216a7d9ebb (diff)
x86/compel/fault-inject: Add a fault-injection for corrupting extended regset
With pseudo-random garbage, the seed is printed with pr_err(). get_task_regs() is called during seizing the task and also for each thread. At this moment only for x86. Signed-off-by: Dmitry Safonov <dima@arista.com>
Diffstat (limited to 'compel')
-rw-r--r--compel/arch/x86/src/lib/cpu.c2
-rw-r--r--compel/arch/x86/src/lib/include/uapi/asm/fpu.h4
-rw-r--r--compel/arch/x86/src/lib/infect.c79
-rw-r--r--compel/include/uapi/infect.h2
4 files changed, 84 insertions, 3 deletions
diff --git a/compel/arch/x86/src/lib/cpu.c b/compel/arch/x86/src/lib/cpu.c
index 617512167..c96f01353 100644
--- a/compel/arch/x86/src/lib/cpu.c
+++ b/compel/arch/x86/src/lib/cpu.c
@@ -125,7 +125,7 @@ static int compel_fpuid(compel_cpuinfo_t *c)
c->xfeatures_mask &= ~(1 << i);
}
- c->xfeatures_mask &= XCNTXT_MASK;
+ c->xfeatures_mask &= XFEATURE_MASK_USER;
c->xfeatures_mask &= ~XFEATURE_MASK_SUPERVISOR;
/*
diff --git a/compel/arch/x86/src/lib/include/uapi/asm/fpu.h b/compel/arch/x86/src/lib/include/uapi/asm/fpu.h
index 4ff531fb9..8985ad7f6 100644
--- a/compel/arch/x86/src/lib/include/uapi/asm/fpu.h
+++ b/compel/arch/x86/src/lib/include/uapi/asm/fpu.h
@@ -76,7 +76,7 @@ enum xfeature {
#define XFEATURE_MASK_SUPERVISOR (XFEATURE_MASK_PT | XFEATURE_HDC)
/* All currently supported features */
-#define XCNTXT_MASK \
+#define XFEATURE_MASK_USER \
(XFEATURE_MASK_FP | XFEATURE_MASK_SSE | \
XFEATURE_MASK_YMM | XFEATURE_MASK_OPMASK | \
XFEATURE_MASK_ZMM_Hi256 | XFEATURE_MASK_Hi16_ZMM | \
@@ -232,7 +232,7 @@ struct pkru_state {
* can vary quite a bit between CPUs.
*
*
- * One page should be enough for the whole xsave state.
+ * One page should be enough for the whole xsave state ;-)
*/
#define EXTENDED_STATE_AREA_SIZE (4096 - sizeof(struct i387_fxsave_struct) - sizeof(struct xsave_hdr_struct))
diff --git a/compel/arch/x86/src/lib/infect.c b/compel/arch/x86/src/lib/infect.c
index 9c4abb60c..401001942 100644
--- a/compel/arch/x86/src/lib/infect.c
+++ b/compel/arch/x86/src/lib/infect.c
@@ -4,6 +4,8 @@
#include <sys/mman.h>
#include <sys/user.h>
#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
#include <compel/asm/fpu.h>
@@ -258,6 +260,80 @@ static int get_task_fpregs(pid_t pid, user_fpregs_struct_t *xsave)
return 0;
}
+/* See arch/x86/kernel/fpu/xstate.c */
+static void validate_random_xstate(struct xsave_struct *xsave)
+{
+ struct xsave_hdr_struct *hdr = &xsave->xsave_hdr;
+ unsigned int i;
+
+ /* No unknown or supervisor features may be set */
+ hdr->xstate_bv &= XFEATURE_MASK_USER;
+ hdr->xstate_bv &= ~XFEATURE_MASK_SUPERVISOR;
+
+ for (i = 0; i < XFEATURE_MAX; i++) {
+ if (!compel_fpu_has_feature(i))
+ hdr->xstate_bv &= ~(1 << i);
+ }
+
+ /* Userspace must use the uncompacted format */
+ hdr->xcomp_bv = 0;
+
+ /*
+ * If 'reserved' is shrunken to add a new field, make sure to validate
+ * that new field here!
+ */
+ BUILD_BUG_ON(sizeof(hdr->reserved) != 48);
+
+ /* No reserved bits may be set */
+ memset(&hdr->reserved, 0, sizeof(hdr->reserved));
+}
+
+/*
+ * TODO: Put fault-injection under CONFIG_* and move
+ * extended regset corruption to generic code
+ */
+static int corrupt_extregs(pid_t pid)
+{
+ bool use_xsave = compel_cpu_has_feature(X86_FEATURE_OSXSAVE);
+ user_fpregs_struct_t ext_regs;
+ int *rand_to = (int *)&ext_regs;
+ unsigned int seed;
+ size_t i;
+
+ seed = time(NULL);
+ for (i = 0; i < sizeof(ext_regs) / sizeof(int); i++)
+ *rand_to++ = rand_r(&seed);
+
+ /*
+ * Error log-level as:
+ * - not intended to be used outside of testing,
+ * - zdtm.py will grep it auto-magically from logs
+ * (and the seed will be known from an automatical testing)
+ */
+ pr_err("Corrupting %s for %d, seed %u\n",
+ use_xsave ? "xsave" : "fpuregs", pid, seed);
+
+ if (!use_xsave) {
+ if (ptrace(PTRACE_SETFPREGS, pid, NULL, &ext_regs)) {
+ pr_perror("Can't set FPU registers for %d", pid);
+ return -1;
+ }
+ } else {
+ struct iovec iov;
+
+ validate_random_xstate((void *)&ext_regs);
+
+ iov.iov_base = &ext_regs;
+ iov.iov_len = sizeof(ext_regs);
+
+ if (ptrace(PTRACE_SETREGSET, pid, (unsigned int)NT_X86_XSTATE, &iov) < 0) {
+ pr_perror("Can't set xstate for %d", pid);
+ return -1;
+ }
+ }
+ return 0;
+}
+
int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
void *arg, unsigned long flags)
{
@@ -309,6 +385,9 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save,
ret = get_task_xsave(pid, &xsave);
}
+ if (!ret && unlikely(flags & INFECT_CORRUPT_EXTREGS))
+ ret = corrupt_extregs(pid);
+
if (ret)
goto err;
diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h
index fa326eafe..6cf3daf46 100644
--- a/compel/include/uapi/infect.h
+++ b/compel/include/uapi/infect.h
@@ -136,6 +136,8 @@ extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *);
#define INFECT_COMPATIBLE (1UL << 3)
/* Workaround for ptrace bug on Skylake CPUs with kernels older than v4.14 */
#define INFECT_X86_PTRACE_MXCSR_BUG (1UL << 4)
+/* After infecting - corrupt extended registers (fault-injection) */
+#define INFECT_CORRUPT_EXTREGS (1UL << 5)
/*
* There are several ways to describe a blob to compel