lkml.org 
[lkml]   [2021]   [Jul]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v7 13/26] x86/fpu/xstate: Support ptracer-induced XSTATE buffer expansion
Date
ptrace() may update XSTATE data before the target task has taken an XFD
fault and expanded the XSTATE buffer. Detect this case and allocate a
sufficient buffer to support the request. Also, disable the (now
unnecessary) associated first-use fault.

Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Reviewed-by: Len Brown <len.brown@intel.com>
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
---
Changes from v5:
* Adjusted to use 'tmpbuf' for the new base code.

Changes from v4:
* Improved the condition check for the expansion.
* Simplified the XSTATE_BV retrieval.
* Updated the code comment.

Changes from v3:
* Removed 'no functional changes' in the changelog. (Borislav Petkov)

Changes from v2:
* Updated the changelog with task->fpu removed. (Borislav Petkov)
* Updated the code comments.
---
arch/x86/kernel/fpu/regset.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)

diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c
index 73d7d7b489fe..244e672c3e3d 100644
--- a/arch/x86/kernel/fpu/regset.c
+++ b/arch/x86/kernel/fpu/regset.c
@@ -163,6 +163,30 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
}
}

+ /*
+ * When a ptracer attempts to write any dynamic user state in the
+ * target buffer but not sufficiently allocated, it dynamically
+ * expands the buffer.
+ *
+ * Check if the expansion is possibly needed.
+ */
+ if (xfeatures_mask_user_dynamic &&
+ ((fpu->state_mask & xfeatures_mask_user_dynamic) != xfeatures_mask_user_dynamic)) {
+ u64 state_mask;
+
+ /* Retrieve XSTATE_BV. */
+ memcpy(&state_mask, (kbuf ?: tmpbuf) + offsetof(struct xregs_state, header),
+ sizeof(u64));
+
+ /* Expand the xstate buffer based on the XSTATE_BV. */
+ state_mask &= xfeatures_mask_user_dynamic;
+ if (state_mask) {
+ ret = alloc_xstate_buffer(fpu, state_mask);
+ if (ret)
+ goto out;
+ }
+ }
+
fpu_force_restore(fpu);
ret = copy_uabi_from_kernel_to_xstate(fpu, kbuf ?: tmpbuf);

--
2.17.1
\
 
 \ /
  Last update: 2021-07-10 15:09    [W:0.113 / U:0.224 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site