<div dir="ltr"><div>The presence of those 4 different zeroing modes feels to me like this gcc feature was added speculatively -- with the intent of gathering some data on the various tradeoffs and impacts of the different options, rather than with the expectation that it's necessarily going to be actually useful. Has that investigation already been done? If so, which of the modes is useful, and for what?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Aug 7, 2020 at 4:18 AM David Chisnall via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Bill,<br>
<br>
The thing missing from the RFC, though tangentially referenced in a couple of the links, is the threat model for this.<br>
<br>
We’ve looked in the past (and had a paper at EuroS&P a few years ago) at the ways in which the compiler can leak secrets that the C abstract machine believes are erased but can be found via a stack memory safety gadget. Fully addressing this requires zeroing spill slots and may also require spilling temporary registers across calls rather than placing values in callee-save registers (though if *all* code is compiled defensively, then the callee can be trusted to zero spill slots for these).<br>
<br>
It appears as if this proposal is to address a weaker security model: leaking secrets via transient execution vulnerabilities. As such, it is not concerned with secrets spilled to the stack or leaked from the caller to callee in callee-save registers. <br>
<br>
The latter almost makes sense. These registers are normally spilled unconditionally on entry to a function if they are used. The presence of shrink wrapping invalidates this assumption though, and there are transient execution paths through a function that uses shrink wrapping that will leak secrets from the caller. I would therefore expect that this option would disable shrink wrapping.<br>
<br>
The former makes less sense to me. Anything that loads from the stack and does something with the result is a potential gadget for leaking secrets spilled to the stack by a prior call via transient execution side channels and, even in the presence of this defence, it seems likely that there are a large number of useful gadgets remaining. <br>
<br>
I think it would be useful for the discussion to have a clear threat model that this intends to defend against and a rough analysis of the security benefits that this is believed to bring. <br>
<br>
David<br>
<br>
> On 7 Aug 2020, at 00:12, Bill Wendling via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br>
> <br>
> [This feature addresses <a href="https://bugs.llvm.org/show_bug.cgi?id=37880" rel="noreferrer" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=37880</a><br>
> and <a href="https://github.com/KSPP/linux/issues/84" rel="noreferrer" target="_blank">https://github.com/KSPP/linux/issues/84</a>.]<br>
> <br>
> Clang has been ramping up its support of the Linux kernel. We recently<br>
> added "asm goto with outputs", a long requested feature. We want to<br>
> continue building our relationship with the Linux community.<br>
> <br>
> KSPP is a project to improve security in the Linux kernel, through<br>
> both kernel changes and compiler features. One compiler feature they<br>
> want is the ability to zero out caller-saved registers on function<br>
> return as a defense against stale register contents being used as a<br>
> side-channel or speculation path.<br>
> <br>
> The option will be "opt-in" for each target. Targets that don't<br>
> support the flag should probably emit a warning or error.<br>
> <br>
> Our proposal for the feature is modeled off of H. J. Lu's<br>
> description[1] (copied with some modifications):<br>
> <br>
> ```<br>
> Add -mzero-caller-saved-regs=[skip|used-gpr|all-gpr|used|all]<br>
> command-line option and zero_caller_saved_regs function attributes:<br>
> <br>
> * Don't zero caller-saved registers upon function return (default):<br>
> <br>
> -mzero-caller-saved-regs=skip<br>
> zero_caller_saved_regs("skip")<br>
> <br>
> * Zero used caller-saved integer registers upon function return:<br>
> <br>
> -mzero-caller-saved-regs=used-gpr<br>
> zero_caller_saved_regs("used-gpr")<br>
> <br>
> * Zero all integer registers upon function return:<br>
> <br>
> -mzero-caller-saved-regs=all-gpr<br>
> zero_caller_saved_regs("all-gpr")<br>
> <br>
> * Zero used caller-saved integer and vector registers upon function return:<br>
> <br>
> -mzero-caller-saved-regs=used<br>
> zero_caller_saved_regs("used")<br>
> <br>
> * Zero all caller-saved integer and vector registers upon function return:<br>
> <br>
> -mzero-caller-saved-regs=all<br>
> zero_caller_saved_regs("all")<br>
> ```<br>
> <br>
> -bw<br>
> <br>
> [1] <a href="https://github.com/clearlinux-pkgs/gcc/blob/master/0001-x86-Add-mzero-caller.patch" rel="noreferrer" target="_blank">https://github.com/clearlinux-pkgs/gcc/blob/master/0001-x86-Add-mzero-caller.patch</a><br>
> _______________________________________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
> <br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div>