[PATCH] D110869: [X86] Implement -fzero-call-used-regs option

Kees Cook via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 8 00:39:15 PST 2022


kees added a comment.

I can build and boot with this. Nice! :) One issue I see is in instruction sequence ordering.

Looking at the end of `__startup_64` without the feature enabled, everything looks "normal":

  31 c0      xor    %eax,%eax
  5b         pop    %rbx
  41 5e      pop    %r14
  41 5f      pop    %r15
  5d         pop    %rbp
  c3         ret

with `-fzero-call-used-regs=used-gpr`:

  31 c0      xor    %eax,%eax
  31 c9      xor    %ecx,%ecx
  31 ff      xor    %edi,%edi
  31 d2      xor    %edx,%edx
  31 f6      xor    %esi,%esi
  45 31 c0   xor    %r8d,%r8d
  45 31 c9   xor    %r9d,%r9d
  45 31 d2   xor    %r10d,%r10d
  45 31 db   xor    %r11d,%r11d
  5b         pop    %rbx
  41 5e      pop    %r14
  41 5f      pop    %r15
  5d         pop    %rbp
  c3         ret

The registers are being wiped, and that's what's needed for the "reducing data lifetime" part of this feature, but because of the ordering, it is not really making ROP attacks harder since all the `pop` instructions are available before the `ret`. I would have expected:

  31 c0      xor    %eax,%eax
  5b         pop    %rbx
  41 5e      pop    %r14
  41 5f      pop    %r15
  5d         pop    %rbp
  31 c9      xor    %ecx,%ecx
  31 ff      xor    %edi,%edi
  31 d2      xor    %edx,%edx
  31 f6      xor    %esi,%esi
  45 31 c0   xor    %r8d,%r8d
  45 31 c9   xor    %r9d,%r9d
  45 31 d2   xor    %r10d,%r10d
  45 31 db   xor    %r11d,%r11d
  c3         ret

And looking at the results with GCC, that's effectively the case. (They're still using `xor`+`mov`, but I'm expecting them <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101891> to switch to all-`xor`.)

  31 c0      xor    %eax,%eax
  5b         pop    %rbx
  5d         pop    %rbp
  41 5c      pop    %r12
  31 d2      xor    %edx,%edx
  89 d1      mov    %edx,%ecx
  89 d6      mov    %edx,%esi
  89 d7      mov    %edx,%edi
  41 89 d0   mov    %edx,%r8d
  41 89 d1   mov    %edx,%r9d
  41 89 d2   mov    %edx,%r10d
  41 89 d3   mov    %edx,%r11d
  c3         ret

With that swapped around, this will be looking great! :)

Some more details about the anti-ROP-ness are here:
https://git.kernel.org/linus/a82adfd5c7cb4b8bb37ef439aed954f9972bb618


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D110869/new/

https://reviews.llvm.org/D110869



More information about the llvm-commits mailing list