3 ms·
Cool. If I understand the LLVM code correctly, it's inserting the following instruction sequence into the code: mov r11, [cookie] xor r11, [rsp] ..
by nneonneo 8y ago
Cool. If I understand the LLVM code correctly, it's inserting the following instruction sequence into the code:
mov r11, [cookie]
xor r11, [rsp]
...
xor r11, [rsp]
cmp r11, [cookie]
jeq 2
int 3
int 3
ret
(where r11 might be some other suitable temp register as needed). cookie points to an 8-byte chunk of .openbsd.randomdata, a section that is initialized at binary load time by the kernel to contain random data. The canary is one of 4000 possible values, named "__retguard_0" through "__retguard_3999", presumably to avoid having the kernel generate an unbounded amount of random data - the section is limited to 1MB in size.
This makes ret instructions fairly hard to use for rop purposes. Unlike the original design, which xor'd [rsp] directly, this new approach preserves return prediction so it should have a lesser effect on performance. With the changes to reduce polymorphic gadgets in place, this should make ROP attacks significantly less palatable. Also, in the original design, an arbitrary leak made rop attacks feasible as you could just place xor-encrypted return addresses on the stack. With the new design, you need repeatable register control too, assuming the temp register isn't spilled, which raises the bar quite a bit.