memcpy is leaking secret data through ZMM vector registers
Jan Sebastian Götte
linux@jaseg.de
Wed Aug 12 16:53:16 GMT 2026
Hi Wilco,
On 8/12/26 18:43, Wilco Dijkstra wrote:
> Leaking register contents will always be true for all GLIBC functions that you might
> call with "secrets" - that's unavoidable since clearing registers is neither the default,
> nor something that assembly implementations support (and rebuilding everything
> with -fzero-call-used-regs would add a huge amount of overhead...
I agree, I don't think there's an easy solution to this on the glibc
side. A solution I could imagine would be putting an
__attribute__((zero_call_used_regs("used"))) on memcpy in particular,
but you'd have to carefully check the performance impact of that,
especially on ARM64.
I think the odd thing about this leak compared to a gpr leak is how long
the SIMD registers can survive after the memcpy call. In my case, they
survived into a crash dump taken tens of seconds after the secrets were
deleted from memory simply because nothing else used SIMD code.
> The best solution is to not call library functions with "secrets" so you don't create that
> problem.
I feel like nobody is really aware of this hazard with memcpy in
particular. People know these days to use something like
"memzero_explicit" with secrets, but I think memcpy is generally
considered safe.
> Alternatively, you could call memcpy with some non-secret data so that it
> overwrites the vector registers. Quite easy as a solution without introducing new
> symbols or having to rewrite assembly code to clear registers etc.
That would be one solution, but it would require me to make some
assumption about how much data I have to put in to get into the fast,
SIMD accelerated code path that fully utilizes these registers. It's
also something that I imagine could be optimized out by an eager compiler.
Jan
More information about the Libc-alpha
mailing list