On Mon, Jun 17, 2024 at 08:54:46PM -0500, Peter Bergner wrote: > On 6/17/24 7:57 PM, Segher Boessenkool wrote: > > On Mon, Jun 17, 2024 at 06:49:18PM -0500, Peter Bergner wrote: > >> On 6/17/24 6:11 PM, Segher Boessenkool wrote: > >> Yeah, I didn't write that, I only moved it, but I can try to come up with > >> an explanation of why we need to disable it now. That said, my hope is to > >> not have to disable shrink-wrapping even when we emit the ROP protect hash > >> insns in the future, but that will take some extra work. If I can manage > >> that, then this should all just go away. :-) Until then, we can stick > >> with this patch's micro-optimization. > > > > If you inline one function into another, there is no ROP protection on > > their boundary anymore (since there is no such boundary anymore!) This > > is not necessarily a problem, but you do want some noipa or similar > > markup where without ROP protection you have no incentive to do that. > > > > Shrink-wrapping allows more inlining, and more inlining allows more > > shrink-wrapping, but there is no direct relation between shrink-wrapping > > and our ROP protect stuff? We just need to make sure the hashst and > > hashchk things are done at the very start and the very end of the > > functions, but we need to make sure of that anyway! > > > > So yeah, please investigate a bit more :-) > > So we should be able to shrink-wrap in the presence of the ROP protection.
Well of course, if we really *cannot* currently that obviously is just a bug. But do we want to? And, how far, in what cases not? In extremis everything is inlined into main(), and -mrop-protect doesn't do any protection. This can be done for *any* program btw. In practice this isn't likely to happen so much. But we need to monitor -- a lot of (target, and backend) optimisations try to reduce nesting overhead, usually by nesting less. And -mrop-protect only does anything at function boundaries :-) > The ROP attacks work by buffer overrun type issues, clobbering the return > address that was saved on the stack causing us to return to somewhere else. Buffer overflows on the stack are the easiest / most common way to do this, yes. But there are other ways to do a return address overwrite. Not as easy to exploit by far, in most programs, sure. > If we don't need to save the return address on the stack like for leaf > functions, or shrink-wrapped sections that are call free, those codes > are not really susceptible to ROP attacks. That is true in some way, yes. Your caller will still check the chain (albeit later). > It's the call paths where we > save the return address on the stack that we have to protect. If inlining > or shrink wrapping increases the amount of code that is call free (ie, we > don't need to save the return address), then that code is not less safe > than before but as safe or safer than before. It seems the reason we > disabled shrink-wrapping now, was that we were emitting the hashst in the > wrong location (PR101324) causing us to store a bad hash value. I think > that was just a "bug" that probably should have been fixed rather than > worked around by disabling shrink-wrapping. It's on my TODO to take a > look at fixing that correctly. Sounds good! Segher