mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
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: b93e685ecf ("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>
This commit is contained in:
parent
a13c140cc2
commit
c3f83d0211
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user