PING [Patch][Middle-end]Add -fzero-call-used-regs=[skip|used-gpr|all-gpr|used|all]
Thu Aug 6 15:45:26 GMT 2020
> On Aug 6, 2020, at 3:37 AM, Richard Biener <email@example.com> wrote:
> On Wed, 5 Aug 2020, Qing Zhao wrote:
>>>> From The SECURE project and GCC in GCC Cauldron 2018:
>>>> Speaker: Graham Markall
>>>> The SECURE project is a 15 month program funded by Innovate UK, to
>>>> take well known security techniques from academia and make them
>>>> generally available in standard compilers, specfically GCC and LLVM.
>>>> An explicit objective is for those techniques to be incorporated in
>>>> the upstream versions of compilers. The Cauldron takes place in the
>>>> final month of the project and this talk will present the technical
>>>> details of some of the techniques implemented, and review those that
>>>> are yet to be implemented. A particular focus of this talk will be on
>>>> verifying that the implemetnation is correct, which can be a bigger
>>>> challenge than the implementation.
>>>> Techniques to be covered in the project include the following:
>>>> Stack and register erasure. Ensuring that on return from a function,
>>>> no data is left lying on the stack or in registers. Particular
>>>> challenges are in dealing with inlining, shrink wrapping and caching.
>>>> This patch implemens register erasure.
>>> Part of it, yes. While I can see abnormal transfer of control is difficult exception handling is used too wide spread to be ignored. What's the plan there?
>>> So can we also see the other parts? In particular I wonder whether exposing just register clearing (in this fine-grained manner) is required and useful rather than thinking of a better interface for the whole thing?
>> You mean to provide an integrated interface for both stack and register
>> erasure for security purpose?
>> However, Is stack erasure at function return really a better idea than
>> zero-init auto-variables in the beginning of the function?
>> We had some discussion with Kees Cook several weeks ago on the idea of
>> stack erasure at function return, Kees provided the following comments:
>> "But back to why I don't think it's the right approach:
>> Based on the performance measurements of pattern-init and zero-init
>> in Clang, MSVC, and the kernel plugin, it's clear that adding these
>> initializations has measurable performance cost. Doing it at function
>> exit means performing large unconditional wipes. Doing it at function
>> entry means initializations can be dead-store eliminated and highly
>> optimized. Given the current debates on the measurable performance
>> difference between pattern and zero initialization (even in the face of
>> existing dead-store elimination), I would expect wipe-on-function-exit to
>> be outside the acceptable tolerance for performance impact. (Additionally,
>> we've seen negative cache effects on wiping memory when the CPU is done
>> using it, though this is more pronounced in heap wiping. Zeroing at
>> free is about twice as expensive as zeroing at free time due to cache
>> temporality. This is true for the stack as well, but it's not as high.)”
>> From my understanding, the major issue with stack erasure at function
>> result is the big performance overhead, And these performance overhead
>> cannot be reduced with compiler optimizations since those additional
>> wiping insns are inserted at the end of the routine.
>> Based on the previous discussion with Kees, I don’t think that stack
>> erasure at function return is a good idea, Instead, we might provide an
>> alternative approach: zero/pattern init to auto-variables. (This
>> functionality has Been available in LLVM already) This will be another
>> patch we want to add to GCC for the security purpose in general.
>> So, I think for the current patch, -fzero-call-used-regs should be good
>> Any comments?
> OK, so -fzero-call-used-regs is a ROP mitigation technique. To me
> it sounded more like a mitigation against information leaks which
> then would be highly incomplete w/o spill slot clearing.
With the “spill slot clearing”, do you mean the “stack erasure” or something else?
From the paper
"Clean the Scratch Registers: A Way to Mitigate Return-Oriented Programming Attacks"
The call-used registers are used by the ROP hackers as following:
"Based on the practical experience of reading and writing ROP code. we find the features of ROP attacks as follows.
First, the destination of using gadget chains in usual is performing system call or system function to perform
malicious behaviour such as file access, network access and W ⊕ X disable. In most cases, the adversary
would like to disable W ⊕ X. Because once W ⊕ X has been disabled, shellcode can be executed directly
instead of rewritting shellcode to ROP chains which may cause some troubles for the adversary. In upper
example, the system call is number 59 which is “execve” system call.
Second, if the adversary performs ROP attacks using system call instruction, no matter on x86 or x64
architecture, the register would be used to pass parameter. Or if the adversary performs ROP attacks
using system function such as “read” or “mprotect”, on x64 system, the register would still be used to
pass parameters, as mentioned in subsection B and C.”
We can see that call-used registers might be used by the ROP hackers to pass parameters to the system call.
If compiler can clean these registers before routine “return", then ROP attack will be invalid.
> we had that discussion on secure erase of memory that should not
> be DSEd.
> This needs to be reflected in the documentation and eventually
> the option naming? Like -frop-protection=... similar in spirit
> to how we have -fcf-protection=... (though that as well is supposed
> to provide ROP mitigation).
How about -frop-mitigation=[skip|used-gpr|all-gpr|used|all]?
> I'm not very familiar with ROP [mitigation] techinques, so I'm no
> longer questioning usefulness of this patch but leave that to others
> (and thus final approval). I'm continuing to question the plethora
> of target hooks you add and will ask for better user-level documentation.
Will think this more and come up with a better user-level documentation .
More information about the Gcc-patches