Theo de Raadt writes: > Yes there are tools for that. google for "rop gadget scanner" and you'll > find the first few. > > But that isn't the right approach. > > If you find just one gadget, how do you react? You can't the constant table > to have different values. > > You move the table to rodata. So why not skip the scanning approach, and > move them all to rodata? > > Because that is exactly where the data belongs. The C versions of these > functions use 'const', and it goes to rodata.
It makes perfect sense to me that the tables in particular ought to go back in .rodata (as they are, well, read-only data). I wouldn't think that optimizations should be allowed to bypass code/data separation policies. There might also be a benefit to setting a goal of ROP gadget reduction in the executable code that's generated by compilers, since a compiler will potentially generate quite a lot of 0xc3 bytes (and other further ROP-sensitive things) if it isn't specifically told not to. Currently I see the .text section of something as simple as /bin/ls with 623 0xc3 bytes that disassemble as retq instructions, plus an additional 116 0xc3 bytes that are part of a longer instruction. For the .text section in the /usr/bin/openssl binary, it seems to be 316 and 145, respectively (presumably because so much of the actual functionality has been broken out into libssl and libcrypto). So, would the marginal benefit of moving the tables to .rodata, without other attempts to reduce ROP gadget availability in libraries and binaries, be very high in terms of the feasibility of ROP to an attacker?
