[PATCH 03/15] crypto: arm64/aes - Fix 32-bit aes_mac_update() arg treated as 64-bit

Eric Biggers ebiggers at kernel.org
Thu Feb 19 13:26:11 PST 2026


On Thu, Feb 19, 2026 at 10:23:39AM +0100, Ard Biesheuvel wrote:
> On Wed, 18 Feb 2026, at 22:34, Eric Biggers wrote:
> > Since the 'enc_after' argument to neon_aes_mac_update() and
> > ce_aes_mac_update() has type 'int', it needs to be accessed using the
> > corresponding 32-bit register, not the 64-bit register.  The upper half
> > of the corresponding 64-bit register may contain garbage.
> 
> How could that happen? Setting the 32-bit alias of a GPR clears the upper half.

The ABI doesn't guarantee that the upper 32 bits are cleared.  Try the
following:

void g(unsigned int a);

void f(unsigned long long a)
{
	g((unsigned int)a);
}

Both gcc and clang generate code that simply tail-calls g(), leaving the
upper 32 bits unchanged rather than zeroing them as per the cast:

0000000000000000 <f>:
       0: 14000000     	b	0x0 <f>

So it's possible.  Now, it's certainly unlikely to happen in practice,
as the real code doesn't use truncating casts like that, and the
instructions that write to the 32-bit registers clear the upper 64 bits
-- as you noted and as I've noted before in similar fixes (e.g.
https://lore.kernel.org/r/20251102234209.62133-2-ebiggers@kernel.org/).

So does it really matter?  Probably not.  However, given that the
correct behavior wasn't *guaranteed*, I think that to be safe we should
continue to consider patches like this to be bugfixes.

- Eric



More information about the linux-arm-kernel mailing list