]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
arm64: RSI: fix field-spanning write warning in attestation token init
authorKohei Enju <enju.kohei@fujitsu.com>
Wed, 15 Jul 2026 12:28:50 +0000 (21:28 +0900)
committerWill Deacon <will@kernel.org>
Sun, 26 Jul 2026 14:22:46 +0000 (14:22 +0000)
The challenge is passed in registers a1 through a8. However, copying to
&regs.a1 makes FORTIFY treat the destination as the single a1 field,
resulting in a field-spanning write warning. [1]

Overlay the SMCCC register structure with an RSI-specific argument
layout and copy the challenge into an explicit 64-byte array. This keeps
the existing a1-a8 argument encoding while giving the copy a correctly
sized destination object.

[1]
memcpy: detected field-spanning write (size 64) of single field "&regs.a1" at ./arch/arm64/include/asm/rsi_cmds.h:119 (size 8)
WARNING: ./arch/arm64/include/asm/rsi_cmds.h:119 at rsi_attestation_token_init+0xdc/0xf8 [arm_cca_guest], CPU#0: cat/3314

Fixes: b880a80011f5 ("arm64: rsi: Add RSI definitions")
Signed-off-by: Kohei Enju <enju.kohei@fujitsu.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/rsi_cmds.h

index 2c8763876dfb773af2efcfea82f336eae2139086..c1fab41f671ec983e39863d76bcfdc3e38bc629b 100644 (file)
@@ -88,6 +88,14 @@ static inline long rsi_set_addr_range_state(phys_addr_t start,
        return res.a0;
 }
 
+#define RSI_ATTEST_CHALLENGE_MIN_SIZE  32
+#define RSI_ATTEST_CHALLENGE_MAX_SIZE  64
+
+struct rsi_attestation_token_init_args {
+       unsigned long fid;
+       u8 challenge[RSI_ATTEST_CHALLENGE_MAX_SIZE];
+};
+
 /**
  * rsi_attestation_token_init - Initialise the operation to retrieve an
  * attestation token.
@@ -109,18 +117,21 @@ static inline long rsi_set_addr_range_state(phys_addr_t start,
 static inline long
 rsi_attestation_token_init(const u8 *challenge, unsigned long size)
 {
-       struct arm_smccc_1_2_regs regs = { 0 };
+       union {
+               struct arm_smccc_1_2_regs regs;
+               struct rsi_attestation_token_init_args init;
+       } args = { 0 };
 
-       /* The challenge must be at least 32bytes and at most 64bytes */
-       if (!challenge || size < 32 || size > 64)
+       if (!challenge || size < RSI_ATTEST_CHALLENGE_MIN_SIZE ||
+           size > RSI_ATTEST_CHALLENGE_MAX_SIZE)
                return -EINVAL;
 
-       regs.a0 = SMC_RSI_ATTESTATION_TOKEN_INIT;
-       memcpy(&regs.a1, challenge, size);
-       arm_smccc_1_2_smc(&regs, &regs);
+       args.init.fid = SMC_RSI_ATTESTATION_TOKEN_INIT;
+       memcpy(args.init.challenge, challenge, size);
+       arm_smccc_1_2_smc(&args.regs, &args.regs);
 
-       if (regs.a0 == RSI_SUCCESS)
-               return regs.a1;
+       if (args.regs.a0 == RSI_SUCCESS)
+               return args.regs.a1;
 
        return -EINVAL;
 }