From 3613b6f15fa8357e8f38f9377c51806e90b452d3 Mon Sep 17 00:00:00 2001 From: Dmitry Safonov Date: Fri, 26 Feb 2021 01:08:00 +0000 Subject: compel: Store extended registers set in the thread context Extended registers set for task is restored with rt_sigreturn() through prepared sigframe. For threads it's currently lost. Preserve it inside thread context to restore on thread curing. Signed-off-by: Dmitry Safonov --- compel/arch/aarch64/src/lib/infect.c | 11 ++++++----- compel/arch/arm/src/lib/infect.c | 9 +++++---- compel/arch/mips/src/lib/infect.c | 8 ++++---- compel/arch/ppc64/src/lib/infect.c | 9 +++++---- compel/arch/s390/src/lib/infect.c | 25 +++++++++++++------------ compel/arch/x86/src/lib/infect.c | 14 +++++++------- 6 files changed, 40 insertions(+), 36 deletions(-) (limited to 'compel/arch') diff --git a/compel/arch/aarch64/src/lib/infect.c b/compel/arch/aarch64/src/lib/infect.c index 4b5939022..39428cd8d 100644 --- a/compel/arch/aarch64/src/lib/infect.c +++ b/compel/arch/aarch64/src/lib/infect.c @@ -60,11 +60,12 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, return 0; } -int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, +int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, + user_fpregs_struct_t *ext_regs, save_regs_t save, void *arg, __maybe_unused unsigned long flags) { + user_fpregs_struct_t tmp, *fpsimd = ext_regs ? ext_regs : &tmp; struct iovec iov; - user_fpregs_struct_t fpsimd; int ret; pr_info("Dumping GP/FPU registers for %d\n", pid); @@ -76,14 +77,14 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, goto err; } - iov.iov_base = &fpsimd; - iov.iov_len = sizeof(fpsimd); + iov.iov_base = fpsimd; + iov.iov_len = sizeof(*fpsimd); if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRFPREG, &iov))) { pr_perror("Failed to obtain FPU registers for %d", pid); goto err; } - ret = save(arg, regs, &fpsimd); + ret = save(arg, regs, fpsimd); err: return ret; } diff --git a/compel/arch/arm/src/lib/infect.c b/compel/arch/arm/src/lib/infect.c index 75b985b74..dd5aa9784 100644 --- a/compel/arch/arm/src/lib/infect.c +++ b/compel/arch/arm/src/lib/infect.c @@ -69,15 +69,16 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, } #define PTRACE_GETVFPREGS 27 -int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, +int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, + user_fpregs_struct_t *ext_regs, save_regs_t save, void *arg, __maybe_unused unsigned long flags) { - user_fpregs_struct_t vfp; + user_fpregs_struct_t tmp, *vfp = ext_regs ? ext_regs : &tmp; int ret = -1; pr_info("Dumping GP/FPU registers for %d\n", pid); - if (ptrace(PTRACE_GETVFPREGS, pid, NULL, &vfp)) { + if (ptrace(PTRACE_GETVFPREGS, pid, NULL, vfp)) { pr_perror("Can't obtain FPU registers for %d", pid); goto err; } @@ -99,7 +100,7 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, } } - ret = save(arg, regs, &vfp); + ret = save(arg, regs, vfp); err: return ret; } diff --git a/compel/arch/mips/src/lib/infect.c b/compel/arch/mips/src/lib/infect.c index 35e947cc0..6a53b3c3b 100755 --- a/compel/arch/mips/src/lib/infect.c +++ b/compel/arch/mips/src/lib/infect.c @@ -122,13 +122,14 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, return 0; } -int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, +int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, + user_fpregs_struct_t *ext_regs, save_regs_t save, void *arg, __maybe_unused unsigned long flags) { - user_fpregs_struct_t xsave = { }, *xs = NULL; + user_fpregs_struct_t xsave = { }, *xs = ext_regs ? ext_regs : &xsave; int ret = -1; - if (ptrace(PTRACE_GETFPREGS, pid, NULL, &xsave)) { + if (ptrace(PTRACE_GETFPREGS, pid, NULL, xs)) { pr_perror("Can't obtain FPU registers for %d", pid); return ret; } @@ -151,7 +152,6 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, regs->regs[0] = 0; } - xs = &xsave; ret = save(arg, regs, xs); return ret; } diff --git a/compel/arch/ppc64/src/lib/infect.c b/compel/arch/ppc64/src/lib/infect.c index b2c725f62..339e01209 100644 --- a/compel/arch/ppc64/src/lib/infect.c +++ b/compel/arch/ppc64/src/lib/infect.c @@ -372,17 +372,18 @@ static int __get_task_regs(pid_t pid, user_regs_struct_t *regs, return 0; } -int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, +int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, + user_fpregs_struct_t *ext_regs, save_regs_t save, void *arg, __maybe_unused unsigned long flags) { - user_fpregs_struct_t fpregs; + user_fpregs_struct_t tmp, *fpregs = ext_regs ? ext_regs : &tmp; int ret; - ret = __get_task_regs(pid, regs, &fpregs); + ret = __get_task_regs(pid, regs, fpregs); if (ret) return ret; - return save(arg, regs, &fpregs); + return save(arg, regs, fpregs); } int compel_syscall(struct parasite_ctl *ctl, int nr, long *ret, diff --git a/compel/arch/s390/src/lib/infect.c b/compel/arch/s390/src/lib/infect.c index 5a4675449..5b3c0d62e 100644 --- a/compel/arch/s390/src/lib/infect.c +++ b/compel/arch/s390/src/lib/infect.c @@ -310,31 +310,32 @@ static int s390_disable_ri_bit(pid_t pid, user_regs_struct_t *regs) /* * Prepare task registers for restart */ -int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, +int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, + user_fpregs_struct_t *ext_regs, save_regs_t save, void *arg, __maybe_unused unsigned long flags) { - user_fpregs_struct_t fpregs; + user_fpregs_struct_t tmp, *fpregs = ext_regs ? ext_regs : &tmp; struct iovec iov; int rewind; - print_user_regs_struct("get_task_regs", pid, regs); + print_user_regs_struct("compel_get_task_regs", pid, regs); - memset(&fpregs, 0, sizeof(fpregs)); - iov.iov_base = &fpregs.prfpreg; - iov.iov_len = sizeof(fpregs.prfpreg); + memset(fpregs, 0, sizeof(*fpregs)); + iov.iov_base = &fpregs->prfpreg; + iov.iov_len = sizeof(fpregs->prfpreg); if (ptrace(PTRACE_GETREGSET, pid, NT_PRFPREG, &iov) < 0) { pr_perror("Couldn't get floating-point registers"); return -1; } - if (get_vx_regs(pid, &fpregs)) { + if (get_vx_regs(pid, fpregs)) { pr_perror("Couldn't get vector registers"); return -1; } - if (get_gs_cb(pid, &fpregs)) { + if (get_gs_cb(pid, fpregs)) { pr_perror("Couldn't get guarded-storage"); return -1; } - if (get_ri_cb(pid, &fpregs)) { + if (get_ri_cb(pid, fpregs)) { pr_perror("Couldn't get runtime-instrumentation"); return -1; } @@ -343,10 +344,10 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, * before we execute parasite code. Otherwise parasite operations * would be recorded. */ - if (fpregs.flags & USER_RI_ON) + if (fpregs->flags & USER_RI_ON) s390_disable_ri_bit(pid, regs); - print_user_fpregs_struct("get_task_regs", pid, &fpregs); + print_user_fpregs_struct("compel_get_task_regs", pid, fpregs); /* Check for system call restarting. */ if (regs->system_call) { rewind = regs->system_call >> 16; @@ -366,7 +367,7 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, } } /* Call save_task_regs() */ - return save(arg, regs, &fpregs); + return save(arg, regs, fpregs); } /* diff --git a/compel/arch/x86/src/lib/infect.c b/compel/arch/x86/src/lib/infect.c index 401001942..9d81083f7 100644 --- a/compel/arch/x86/src/lib/infect.c +++ b/compel/arch/x86/src/lib/infect.c @@ -334,10 +334,11 @@ static int corrupt_extregs(pid_t pid) return 0; } -int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, +int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, + user_fpregs_struct_t *ext_regs, save_regs_t save, void *arg, unsigned long flags) { - user_fpregs_struct_t xsave = { }, *xs = NULL; + user_fpregs_struct_t xsave = { }, *xs = ext_regs ? ext_regs : &xsave; int ret = -1; pr_info("Dumping general registers for %d in %s mode\n", pid, @@ -371,18 +372,18 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, pr_info("Dumping GP/FPU registers for %d\n", pid); if (!compel_cpu_has_feature(X86_FEATURE_OSXSAVE)) { - ret = get_task_fpregs(pid, &xsave); + ret = get_task_fpregs(pid, xs); } else if (unlikely(flags & INFECT_X86_PTRACE_MXCSR_BUG)) { /* * get_task_fpregs() will fill FP state, * get_task_xsave() will overwrite rightly sse/mmx/etc */ pr_warn("Skylake xsave fpu bug workaround used\n"); - ret = get_task_fpregs(pid, &xsave); + ret = get_task_fpregs(pid, xs); if (!ret) - ret = get_task_xsave(pid, &xsave); + ret = get_task_xsave(pid, xs); } else { - ret = get_task_xsave(pid, &xsave); + ret = get_task_xsave(pid, xs); } if (!ret && unlikely(flags & INFECT_CORRUPT_EXTREGS)) @@ -391,7 +392,6 @@ int get_task_regs(pid_t pid, user_regs_struct_t *regs, save_regs_t save, if (ret) goto err; - xs = &xsave; out: ret = save(arg, regs, xs); err: -- cgit v1.2.3