summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Mehltretter <kmehltretter@gmail.com>2026-07-29 02:42:54 +0200
committerWill Deacon <will@kernel.org>2026-08-02 09:46:07 +0000
commitc3f83d021162571bcd87b062ec9e587828d2b7f3 (patch)
tree4ab335ab7eb5f4a15b0c278323df60e24b74883f
parenta13c140cc289c0b7b3770bce5b3ad42ab35074aa (diff)
downloadlinux-next-c3f83d021162571bcd87b062ec9e587828d2b7f3.tar.gz
linux-next-c3f83d021162571bcd87b062ec9e587828d2b7f3.zip
arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets
sve_init_header_from_task() takes header as a pointer, so for the inactive mode header->size = sizeof(header); stores 8 rather than sizeof(struct user_sve_header), which is 16. Userspace sees an impossible size smaller than the header it describes. The inactive-mode check in sve_get_common() compares header.size against sizeof(header) as well, but there header is a struct, so the check can never fire. Reads of NT_ARM_SVE and NT_ARM_SSVE for the inactive mode therefore still return the other mode's FPSIMD data, exactly the situation the check was added to prevent. Fix the size, and make the check return the remaining membuf space instead of 0, which regset_get() would interpret as the entire (zero-filled) buffer having been populated. Fixes: b93e685ecff7 ("arm64/fpsimd: ptrace: Do not present register data for inactive mode") Assisted-by: Claude:claude-opus-5 Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--arch/arm64/kernel/ptrace.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 4d08598e2891..2a72c61a8af9 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -801,7 +801,7 @@ static void sve_init_header_from_task(struct user_sve_header *header,
if (active)
header->size = SVE_PT_SIZE(vq, header->flags);
else
- header->size = sizeof(header);
+ header->size = sizeof(*header);
header->max_size = SVE_PT_SIZE(sve_vq_from_vl(header->max_vl),
SVE_PT_REGS_SVE);
}
@@ -837,7 +837,7 @@ static int sve_get_common(struct task_struct *target,
* from the other mode to userspace.
*/
if (header.size == sizeof(header))
- return 0;
+ return to.left;
switch ((header.flags & SVE_PT_REGS_MASK)) {
case SVE_PT_REGS_FPSIMD: