Kees Cook via Gcc-patches <gcc-patches@gcc.gnu.org> writes: > [tried to clean up quoting...] > > On Tue, Sep 08, 2020 at 10:00:09AM -0500, Qing Zhao wrote: >> >> > On Sep 7, 2020, at 8:06 AM, Rodriguez Bahena, Victor >> > <victor.rodriguez.bah...@intel.com> wrote: >> > >> >>> On Thu, Sep 03, 2020 at 09:29:54AM -0500, Qing Zhao wrote: >> >>> So, my question is: >> >>> >> >>> From the security point of view, does clearing ALL registers have more >> >>> benefit than clearing USED registers? >> >>> From my understanding, clearing registers that are not used in the >> >>> current routine does NOT provide additional benefit, correct me if I am >> >>> wrong here. >> > >> > You are right, it does not provide additional security >> >> Then, is it necessary to provide >> >> -fzero-call-used-regs=all-arg|all-gpr|all to the user? >> >> Can we just delete these 3 sub options? > > Well... I'd say there is some benefit (remember that ROP gadgets are > built from function trailers, so there is rarely a concern over what the > rest of the function is doing). Generally, they are chained together > based on just the last couple instructions: > > *useful action* > *ret* > > So with ...=used this turns into: > > *useful action* > *clear some registers* > *ret* > > Which may still be helpful (if, for example, the state being built by > the attacker is using registers _not_ in the cleared list). However: > > *useful action* > *clear all registers* > *ret* > > Means that suddenly the ROP chain cannot use *any* of the caller-saved > registers to hold state. > > So, while ...=used is likely going to block a lot, ...=all will block > even more. I'd prefer to have both available, if for no other reason > than to compare the ROP gadget availability for any given binary (e.g. > if some future attack is found that bypasses ...=used, does it also > bypass ...=all?)
This might have already been discussed/answered, sorry, but: when there's a choice, is there an obvious winner between: (1) clearing call-clobbered registers and then restoring call-preserved ones (2) restoring call-preserved registers and then clearing call-clobbered ones Is one option more likely to be useful to attackers than the other? (For some frames, it might be necessary to use a small number of call-clobbered registers to perform the restore sequence, so (1) wouldn't be fully achievable in all cases.) Thanks, Richard