mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 15:47:36 +00:00
x86/fpu: Allow PKRU to be (once again) written by ptrace.
Move KVM's PKRU handling code in fpu_copy_uabi_to_guest_fpstate() to
copy_uabi_to_xstate() so that it is shared with other APIs that write the
XSTATE such as PTRACE_SETREGSET with NT_X86_XSTATE.
This restores the pre-5.14 behavior of ptrace. The regression can be seen
by running gdb and executing `p $pkru`, `set $pkru = 42`, and `p $pkru`.
On affected kernels (5.14+) the write to the PKRU register (which gdb
performs through ptrace) is ignored.
[ dhansen: removed stable@ tag for now. The ABI was broken for long
enough that this is not urgent material. Let's let it stew
in tip for a few weeks before it's submitted to stable
because there are so many ABIs potentially affected. ]
Fixes: e84ba47e31
("x86/fpu: Hook up PKRU into ptrace()")
Signed-off-by: Kyle Huey <me@kylehuey.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Link: https://lore.kernel.org/all/20221115230932.7126-5-khuey%40kylehuey.com
This commit is contained in:
parent
2c87767c35
commit
4a804c4f83
2 changed files with 21 additions and 13 deletions
|
@ -391,8 +391,6 @@ int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf,
|
|||
{
|
||||
struct fpstate *kstate = gfpu->fpstate;
|
||||
const union fpregs_state *ustate = buf;
|
||||
struct pkru_state *xpkru;
|
||||
int ret;
|
||||
|
||||
if (!cpu_feature_enabled(X86_FEATURE_XSAVE)) {
|
||||
if (ustate->xsave.header.xfeatures & ~XFEATURE_MASK_FPSSE)
|
||||
|
@ -406,16 +404,7 @@ int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf,
|
|||
if (ustate->xsave.header.xfeatures & ~xcr0)
|
||||
return -EINVAL;
|
||||
|
||||
ret = copy_uabi_from_kernel_to_xstate(kstate, ustate, vpkru);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Retrieve PKRU if not in init state */
|
||||
if (kstate->regs.xsave.header.xfeatures & XFEATURE_MASK_PKRU) {
|
||||
xpkru = get_xsave_addr(&kstate->regs.xsave, XFEATURE_PKRU);
|
||||
*vpkru = xpkru->pkru;
|
||||
}
|
||||
return 0;
|
||||
return copy_uabi_from_kernel_to_xstate(kstate, ustate, vpkru);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fpu_copy_uabi_to_guest_fpstate);
|
||||
#endif /* CONFIG_KVM */
|
||||
|
|
|
@ -1205,10 +1205,22 @@ static int copy_from_buffer(void *dst, unsigned int offset, unsigned int size,
|
|||
* @fpstate: The fpstate buffer to copy to
|
||||
* @kbuf: The UABI format buffer, if it comes from the kernel
|
||||
* @ubuf: The UABI format buffer, if it comes from userspace
|
||||
* @pkru: unused
|
||||
* @pkru: The location to write the PKRU value to
|
||||
*
|
||||
* Converts from the UABI format into the kernel internal hardware
|
||||
* dependent format.
|
||||
*
|
||||
* This function ultimately has three different callers with distinct PKRU
|
||||
* behavior.
|
||||
* 1. When called from sigreturn the PKRU register will be restored from
|
||||
* @fpstate via an XRSTOR. Correctly copying the UABI format buffer to
|
||||
* @fpstate is sufficient to cover this case, but the caller will also
|
||||
* pass a pointer to the thread_struct's pkru field in @pkru and updating
|
||||
* it is harmless.
|
||||
* 2. When called from ptrace the PKRU register will be restored from the
|
||||
* thread_struct's pkru field. A pointer to that is passed in @pkru.
|
||||
* 3. When called from KVM the PKRU register will be restored from the vcpu's
|
||||
* pkru field. A pointer to that is passed in @pkru.
|
||||
*/
|
||||
static int copy_uabi_to_xstate(struct fpstate *fpstate, const void *kbuf,
|
||||
const void __user *ubuf, u32 *pkru)
|
||||
|
@ -1260,6 +1272,13 @@ static int copy_uabi_to_xstate(struct fpstate *fpstate, const void *kbuf,
|
|||
}
|
||||
}
|
||||
|
||||
if (hdr.xfeatures & XFEATURE_MASK_PKRU) {
|
||||
struct pkru_state *xpkru;
|
||||
|
||||
xpkru = __raw_xsave_addr(xsave, XFEATURE_PKRU);
|
||||
*pkru = xpkru->pkru;
|
||||
}
|
||||
|
||||
/*
|
||||
* The state that came in from userspace was user-state only.
|
||||
* Mask all the user states out of 'xfeatures':
|
||||
|
|
Loading…
Reference in a new issue