[cfe-dev] [RFC] Zeroing Caller Saved Regs
James Courtier-Dutton via cfe-dev
cfe-dev at lists.llvm.org
Mon Aug 10 05:07:05 PDT 2020
On Fri, 7 Aug 2020 at 00:12, Bill Wendling via cfe-dev
<cfe-dev at lists.llvm.org> wrote:
>
> [This feature addresses https://bugs.llvm.org/show_bug.cgi?id=37880
> and https://github.com/KSPP/linux/issues/84.]
>
> Clang has been ramping up its support of the Linux kernel. We recently
> added "asm goto with outputs", a long requested feature. We want to
> continue building our relationship with the Linux community.
>
> KSPP is a project to improve security in the Linux kernel, through
> both kernel changes and compiler features. One compiler feature they
> want is the ability to zero out caller-saved registers on function
> return as a defense against stale register contents being used as a
> side-channel or speculation path.
>
> The option will be "opt-in" for each target. Targets that don't
> support the flag should probably emit a warning or error.
>
> Our proposal for the feature is modeled off of H. J. Lu's
> description[1] (copied with some modifications):
>
> ```
> Add -mzero-caller-saved-regs=[skip|used-gpr|all-gpr|used|all]
> command-line option and zero_caller_saved_regs function attributes:
>
> * Don't zero caller-saved registers upon function return (default):
>
> -mzero-caller-saved-regs=skip
> zero_caller_saved_regs("skip")
>
> * Zero used caller-saved integer registers upon function return:
>
> -mzero-caller-saved-regs=used-gpr
> zero_caller_saved_regs("used-gpr")
>
> * Zero all integer registers upon function return:
>
> -mzero-caller-saved-regs=all-gpr
> zero_caller_saved_regs("all-gpr")
>
> * Zero used caller-saved integer and vector registers upon function return:
>
> -mzero-caller-saved-regs=used
> zero_caller_saved_regs("used")
>
> * Zero all caller-saved integer and vector registers upon function return:
>
> -mzero-caller-saved-regs=all
> zero_caller_saved_regs("all")
> ```
>
> -bw
>
> [1] https://github.com/clearlinux-pkgs/gcc/blob/master/0001-x86-Add-mzero-caller.patch
While the above might have a significant impact on performance, adding
this sort of security controls at the C and C++ level would be very
helpful.
e.g.
int function_containing_secret() {
int secret = 12345;
/* do some work with the secret */
secret = 0;
return 0;
}
Now, with compiler optimisations, the last "secret = 0;" will get
optimised out, as there are no uses of it.
Having some way to enforce that the "secret = 0" remains, and at
assembler level, which every registers and temporary stack values it
was stored in are wiped could be a useful addition.
I don't quite understand how the zero-all-values helps in the ROP
case, because the zero-all-value part can be bypassed by the malicious
user.
Kind Regards
James
More information about the cfe-dev
mailing list