[llvm-dev] [RFC] Zeroing Caller Saved Regs

Bill Wendling via llvm-dev llvm-dev at lists.llvm.org
Wed Aug 12 21:01:44 PDT 2020

On Wed, Aug 12, 2020 at 8:38 PM Stephen Checkoway <s at pahtak.org> wrote:
> > On Aug 12, 2020, at 17:44, Bill Wendling via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> >
> > My guess is that inserting zeroing instructions right before the "ret"
> > instruction can disable some of the hacks we see with ROP:
> >
> >   `pop rdi ; ret` becomes `pop rdi ; xor rdi, rdi ; ret`
> Three comments on this.
> 1. The very first ROP paper [1] used only unintended instruction sequences. That is, none of the return instructions were placed there by the compiler, they appeared completely within other instructions.
> 2. ROP doesn't require any return instructions [2]. It can be performed using call or jmp instructions.

Sure, but the authors of the paper claim that it's incredibly
difficult to have *only* COP / JOP gadgets. At some point you'll need
to have an ROP gadget:

"Usually, the gadgets of ROP end with a return instruction which we
called conventional ROP attacks. Call Oriented Programming (COP) [8]
and Jump-Oriented Programming (JOP) [9] are the variations of ROP
attacks without returns [10]. The variations use gadgets that end with
indirect call or jump instruction. However, performing ROP attacks
without return instruction in reality is difficult for the reason that
the gadgets of COP and JOP that can form a completed gadget chain are
almost nonexistent. Actually, adversaries prefer to use combinational
gadgets to evade current protection mechanisms."

> 3. As binaries get larger, the number of available instruction sequences from which one can build gadgets increases dramatically. If the goal is to make one system call like mprotect, you don't need very many at all. If want to get arbitrary computation using ROP and something like mprotect doesn't exist (e.g., on a Harvard architecture machine), you only need a few tens of kilobytes of code. I did it on the Z80 with 16 kB of code with a hardware interlock that forced instructions to be fetched from ROM [3].
> There have been a bunch of defenses that purport to make attacks harder by decreasing the number of useful instruction sequences available to the attacker. They don't have a significant impact on attacks.
> That's not to say that this couldn't be useful, but I'm skeptical it would defend against ROP, or even make a ROP attack much more difficult.
This is why having variable length instructions sucks. :-)

I see your point. I was actually looking at the code we generate with
the pop/xor if you start at different offsets in the code when your
email came in.


More information about the llvm-dev mailing list