* [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets
@ 2026-07-29 0:42 Karl Mehltretter
2026-07-29 0:42 ` [PATCH 2/2] kselftest/arm64: fp-ptrace: Fix checks for " Karl Mehltretter
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Karl Mehltretter @ 2026-07-29 0:42 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon
Cc: Mark Rutland, Mark Brown, Oleg Nesterov, Shuah Khan,
linux-arm-kernel, linux-kselftest, linux-kernel, Karl Mehltretter
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>
---
Found by inspection while reviewing arch/arm64.
Confirmed in the generated code: building arch/arm64/kernel/ptrace.o
with arm64 defconfig and gcc 15.2.0 and disassembling sve_get_common
shows the inactive branch storing a literal 8 into header.size, and no
compare against 16 anywhere - the compiler constant-folds the check
away entirely and falls straight through to __fpr_get(). That is a
machine-checked demonstration that the early return can never fire.
Runtime tested under QEMU TCG with -cpu max,sme=on. Before this
change, PTRACE_GETREGSET(NT_ARM_SSVE) on a tracee outside streaming
mode returned header.size == 8 and copied the 528-byte NT_PRFPREG
payload. Afterwards, header.size is 16 and bytes in the userspace
buffer after the header are left untouched.
arch/arm64/kernel/ptrace.c | 4 ++--
1 file 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:
--
2.51.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] kselftest/arm64: fp-ptrace: Fix checks for inactive SVE and SSVE regsets
2026-07-29 0:42 [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets Karl Mehltretter
@ 2026-07-29 0:42 ` Karl Mehltretter
2026-08-02 12:12 ` [PATCH 1/2] arm64/fpsimd: ptrace: Fix " Will Deacon
2026-08-02 12:12 ` Will Deacon
2 siblings, 0 replies; 8+ messages in thread
From: Karl Mehltretter @ 2026-07-29 0:42 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon
Cc: Mark Rutland, Mark Brown, Oleg Nesterov, Shuah Khan,
linux-arm-kernel, linux-kselftest, linux-kernel, Karl Mehltretter
The checks on the header size reported for the inactive regset of the
NT_ARM_SVE/NT_ARM_SSVE pair compare it against sizeof(sve), but sve is
a struct user_sve_header *, so this is 8 rather than the intended 16.
The kernel carried the identical typo when filling in the header, so
kernel and test agreed on the wrong value and the test passed.
Compare against sizeof(*sve), stop after the header checks for an
inactive regset since it has no payload to compare, and prefill the
buffer with a sentinel to verify that reading an inactive regset
leaves everything after the header untouched. This also covers the
getter's return value, which determines how many bytes ptrace copies
back to userspace.
Fixes: 864f3ddcd715 ("kselftest/arm64: fp-ptrace: Adjust to new inactive mode behaviour")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
With the size comparison fixed, fp-ptrace fails against kernels that
do not have the preceding regset fix.
tools/testing/selftests/arm64/fp/fp-ptrace.c | 47 +++++++++++++++++---
1 file changed, 41 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/arm64/fp/fp-ptrace.c b/tools/testing/selftests/arm64/fp/fp-ptrace.c
index 22c584b78be5..b435837c8c0e 100644
--- a/tools/testing/selftests/arm64/fp/fp-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/fp-ptrace.c
@@ -65,6 +65,9 @@
/* VL 128..2048 in powers of 2 */
#define MAX_NUM_VLS 5
+/* Sentinel for detecting buffer bytes the kernel did not write */
+#define REGSET_SENTINEL 0xa5
+
/*
* FPMR bits we can set without doing feature checks to see if values
* are valid.
@@ -181,6 +184,20 @@ static bool compare_buffer(const char *name, void *out,
return false;
}
+static bool buffer_is_filled(const void *buffer, size_t size,
+ unsigned char value)
+{
+ const unsigned char *bytes = buffer;
+ size_t i;
+
+ for (i = 0; i < size; i++) {
+ if (bytes[i] != value)
+ return false;
+ }
+
+ return true;
+}
+
struct test_config {
int sve_vl_in;
int sve_vl_expected;
@@ -401,6 +418,7 @@ static bool check_ptrace_values_sve(pid_t child, struct test_config *config)
struct user_sve_header *sve;
struct user_fpsimd_state *fpsimd;
struct iovec iov;
+ size_t buf_size;
int ret, vq;
bool pass = true;
@@ -409,14 +427,16 @@ static bool check_ptrace_values_sve(pid_t child, struct test_config *config)
vq = __sve_vq_from_vl(config->sve_vl_in);
- iov.iov_len = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE);
- iov.iov_base = malloc(iov.iov_len);
+ buf_size = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE);
+ iov.iov_len = buf_size;
+ iov.iov_base = malloc(buf_size);
if (!iov.iov_base) {
ksft_print_msg("OOM allocating %lu byte SVE buffer\n",
iov.iov_len);
return false;
}
+ memset(iov.iov_base, REGSET_SENTINEL, buf_size);
ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_SVE, &iov);
if (ret != 0) {
ksft_print_msg("Failed to read initial SVE: %s (%d)\n",
@@ -440,10 +460,16 @@ static bool check_ptrace_values_sve(pid_t child, struct test_config *config)
}
if (svcr_in & SVCR_SM) {
- if (sve->size != sizeof(sve)) {
+ if (sve->size != sizeof(*sve)) {
ksft_print_msg("NT_ARM_SVE reports data with PSTATE.SM\n");
pass = false;
}
+ if (!buffer_is_filled(iov.iov_base + sizeof(*sve),
+ buf_size - sizeof(*sve), REGSET_SENTINEL)) {
+ ksft_print_msg("NT_ARM_SVE wrote beyond its header with PSTATE.SM\n");
+ pass = false;
+ }
+ goto out;
} else {
if (sve->size != SVE_PT_SIZE(vq, sve->flags)) {
ksft_print_msg("Mismatch in SVE header size: %d != %lu\n",
@@ -485,6 +511,7 @@ static bool check_ptrace_values_ssve(pid_t child, struct test_config *config)
struct user_sve_header *sve;
struct user_fpsimd_state *fpsimd;
struct iovec iov;
+ size_t buf_size;
int ret, vq;
bool pass = true;
@@ -493,14 +520,16 @@ static bool check_ptrace_values_ssve(pid_t child, struct test_config *config)
vq = __sve_vq_from_vl(config->sme_vl_in);
- iov.iov_len = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE);
- iov.iov_base = malloc(iov.iov_len);
+ buf_size = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE);
+ iov.iov_len = buf_size;
+ iov.iov_base = malloc(buf_size);
if (!iov.iov_base) {
ksft_print_msg("OOM allocating %lu byte SSVE buffer\n",
iov.iov_len);
return false;
}
+ memset(iov.iov_base, REGSET_SENTINEL, buf_size);
ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_SSVE, &iov);
if (ret != 0) {
ksft_print_msg("Failed to read initial SSVE: %s (%d)\n",
@@ -523,10 +552,16 @@ static bool check_ptrace_values_ssve(pid_t child, struct test_config *config)
}
if (!(svcr_in & SVCR_SM)) {
- if (sve->size != sizeof(sve)) {
+ if (sve->size != sizeof(*sve)) {
ksft_print_msg("NT_ARM_SSVE reports data without PSTATE.SM\n");
pass = false;
}
+ if (!buffer_is_filled(iov.iov_base + sizeof(*sve),
+ buf_size - sizeof(*sve), REGSET_SENTINEL)) {
+ ksft_print_msg("NT_ARM_SSVE wrote beyond its header without PSTATE.SM\n");
+ pass = false;
+ }
+ goto out;
} else {
if (sve->size != SVE_PT_SIZE(vq, sve->flags)) {
ksft_print_msg("Mismatch in SSVE header size: %d != %lu\n",
--
2.51.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets
2026-07-29 0:42 [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets Karl Mehltretter
2026-07-29 0:42 ` [PATCH 2/2] kselftest/arm64: fp-ptrace: Fix checks for " Karl Mehltretter
@ 2026-08-02 12:12 ` Will Deacon
2026-08-05 21:27 ` Mark Brown
2026-08-02 12:12 ` Will Deacon
2 siblings, 1 reply; 8+ messages in thread
From: Will Deacon @ 2026-08-02 12:12 UTC (permalink / raw)
To: Catalin Marinas, Karl Mehltretter
Cc: kernel-team, Will Deacon, Mark Rutland, Mark Brown, Oleg Nesterov,
Shuah Khan, linux-arm-kernel, linux-kselftest, linux-kernel
On Wed, 29 Jul 2026 02:42:54 +0200, Karl Mehltretter wrote:
> 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.
>
> [...]
Applied selftest update to arm64 (for-next/selftests), thanks!
[2/2] kselftest/arm64: fp-ptrace: Fix checks for inactive SVE and SSVE regsets
https://git.kernel.org/arm64/c/bd290e7fc245
Cheers,
--
Will
https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets
2026-07-29 0:42 [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets Karl Mehltretter
2026-07-29 0:42 ` [PATCH 2/2] kselftest/arm64: fp-ptrace: Fix checks for " Karl Mehltretter
2026-08-02 12:12 ` [PATCH 1/2] arm64/fpsimd: ptrace: Fix " Will Deacon
@ 2026-08-02 12:12 ` Will Deacon
2 siblings, 0 replies; 8+ messages in thread
From: Will Deacon @ 2026-08-02 12:12 UTC (permalink / raw)
To: Catalin Marinas, Karl Mehltretter
Cc: kernel-team, Will Deacon, Mark Rutland, Mark Brown, Oleg Nesterov,
Shuah Khan, linux-arm-kernel, linux-kselftest, linux-kernel
On Wed, 29 Jul 2026 02:42:54 +0200, Karl Mehltretter wrote:
> 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.
>
> [...]
Applied fix to arm64 (for-next/ptrace), thanks!
[1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets
https://git.kernel.org/arm64/c/c3f83d021162
Cheers,
--
Will
https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets
2026-08-02 12:12 ` [PATCH 1/2] arm64/fpsimd: ptrace: Fix " Will Deacon
@ 2026-08-05 21:27 ` Mark Brown
2026-08-06 10:57 ` Will Deacon
0 siblings, 1 reply; 8+ messages in thread
From: Mark Brown @ 2026-08-05 21:27 UTC (permalink / raw)
To: Will Deacon
Cc: Catalin Marinas, Karl Mehltretter, kernel-team, Mark Rutland,
Oleg Nesterov, Shuah Khan, linux-arm-kernel, linux-kselftest,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 720 bytes --]
On Sun, Aug 02, 2026 at 01:12:24PM +0100, Will Deacon wrote:
> On Wed, 29 Jul 2026 02:42:54 +0200, Karl Mehltretter wrote:
> > sve_init_header_from_task() takes header as a pointer, so for the
> > inactive mode
> Applied selftest update to arm64 (for-next/selftests), thanks!
> [2/2] kselftest/arm64: fp-ptrace: Fix checks for inactive SVE and SSVE regsets
> https://git.kernel.org/arm64/c/bd290e7fc245
As noted in the changelog applying patch 1 as a fix and this only for
-next blows up the fp-ptrace test rather impressively in any
configuration which can generate headers only reports:
https://lava.sirena.org.uk/scheduler/job/3075737#L3231
for the release. Both patches really do need to go together.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets
2026-08-05 21:27 ` Mark Brown
@ 2026-08-06 10:57 ` Will Deacon
2026-08-06 12:15 ` Mark Brown
0 siblings, 1 reply; 8+ messages in thread
From: Will Deacon @ 2026-08-06 10:57 UTC (permalink / raw)
To: Mark Brown
Cc: Catalin Marinas, Karl Mehltretter, kernel-team, Mark Rutland,
Oleg Nesterov, Shuah Khan, linux-arm-kernel, linux-kselftest,
linux-kernel
On Wed, Aug 05, 2026 at 10:27:18PM +0100, Mark Brown wrote:
> On Sun, Aug 02, 2026 at 01:12:24PM +0100, Will Deacon wrote:
> > On Wed, 29 Jul 2026 02:42:54 +0200, Karl Mehltretter wrote:
> > > sve_init_header_from_task() takes header as a pointer, so for the
> > > inactive mode
>
> > Applied selftest update to arm64 (for-next/selftests), thanks!
>
> > [2/2] kselftest/arm64: fp-ptrace: Fix checks for inactive SVE and SSVE regsets
> > https://git.kernel.org/arm64/c/bd290e7fc245
>
> As noted in the changelog applying patch 1 as a fix and this only for
> -next blows up the fp-ptrace test rather impressively in any
> configuration which can generate headers only reports:
>
> https://lava.sirena.org.uk/scheduler/job/3075737#L3231
>
> for the release. Both patches really do need to go together.
By "blows up" you mean the test fails, right? That's the same behaviour
if anybody runs the test on a kernel without the fix. Both patches are
merged in for-next/core.
Will
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets
2026-08-06 10:57 ` Will Deacon
@ 2026-08-06 12:15 ` Mark Brown
2026-08-06 12:20 ` Will Deacon
0 siblings, 1 reply; 8+ messages in thread
From: Mark Brown @ 2026-08-06 12:15 UTC (permalink / raw)
To: Will Deacon
Cc: Catalin Marinas, Karl Mehltretter, kernel-team, Mark Rutland,
Oleg Nesterov, Shuah Khan, linux-arm-kernel, linux-kselftest,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 848 bytes --]
On Thu, Aug 06, 2026 at 11:57:12AM +0100, Will Deacon wrote:
> On Wed, Aug 05, 2026 at 10:27:18PM +0100, Mark Brown wrote:
> > As noted in the changelog applying patch 1 as a fix and this only for
> > -next blows up the fp-ptrace test rather impressively in any
> > configuration which can generate headers only reports:
> > https://lava.sirena.org.uk/scheduler/job/3075737#L3231
> > for the release. Both patches really do need to go together.
> By "blows up" you mean the test fails, right? That's the same behaviour
> if anybody runs the test on a kernel without the fix. Both patches are
> merged in for-next/core.
Right, the test starts reporting 96 fails which doesn't look great in a
dashboard. I'd misread the original branch as being merged as a fix but
I see it's not been merged into the fixes branch, sorry for the
confusion.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets
2026-08-06 12:15 ` Mark Brown
@ 2026-08-06 12:20 ` Will Deacon
0 siblings, 0 replies; 8+ messages in thread
From: Will Deacon @ 2026-08-06 12:20 UTC (permalink / raw)
To: Mark Brown
Cc: Catalin Marinas, Karl Mehltretter, kernel-team, Mark Rutland,
Oleg Nesterov, Shuah Khan, linux-arm-kernel, linux-kselftest,
linux-kernel
On Thu, Aug 06, 2026 at 01:15:25PM +0100, Mark Brown wrote:
> On Thu, Aug 06, 2026 at 11:57:12AM +0100, Will Deacon wrote:
> > On Wed, Aug 05, 2026 at 10:27:18PM +0100, Mark Brown wrote:
>
> > > As noted in the changelog applying patch 1 as a fix and this only for
> > > -next blows up the fp-ptrace test rather impressively in any
> > > configuration which can generate headers only reports:
>
> > > https://lava.sirena.org.uk/scheduler/job/3075737#L3231
>
> > > for the release. Both patches really do need to go together.
>
> > By "blows up" you mean the test fails, right? That's the same behaviour
> > if anybody runs the test on a kernel without the fix. Both patches are
> > merged in for-next/core.
>
> Right, the test starts reporting 96 fails which doesn't look great in a
> dashboard. I'd misread the original branch as being merged as a fix but
> I see it's not been merged into the fixes branch, sorry for the
> confusion.
No problem, thank you for running the tests :)
Will
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-06 12:20 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 0:42 [PATCH 1/2] arm64/fpsimd: ptrace: Fix inactive SVE and SSVE regsets Karl Mehltretter
2026-07-29 0:42 ` [PATCH 2/2] kselftest/arm64: fp-ptrace: Fix checks for " Karl Mehltretter
2026-08-02 12:12 ` [PATCH 1/2] arm64/fpsimd: ptrace: Fix " Will Deacon
2026-08-05 21:27 ` Mark Brown
2026-08-06 10:57 ` Will Deacon
2026-08-06 12:15 ` Mark Brown
2026-08-06 12:20 ` Will Deacon
2026-08-02 12:12 ` Will Deacon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox