https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112917

Alexandre Oliva <aoliva at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |aoliva at gcc dot 
gnu.org
   Last reconfirmed|                            |2023-12-09

--- Comment #1 from Alexandre Oliva <aoliva at gcc dot gnu.org> ---
Hello, Rainer,

The bulk of the documentation about strub is not at the options, that are
indeed mostly developer-oriented implementation details, but in the attribute,
referenced from the first of the strub options.

It's about stack scrubbing, and the execution tests all follow roughly the same
pattern: there's a body that gets a certain string onto the stack, a check
before scrubbing that the string is there, and a check after scrubbing that the
string is no longer there.

I'm afraid I haven't had access to sparc hardware in a very long time; the
sparc machines in the compile farm that I used before have long been down, and
the solaris ones there aren't letting me in for some reason.

I've looked at the asm output for the tests, and I see nothing particularly
wrong.  What's probably happening is that the test_string, stored in the s
buffer within leak_string(), is getting into the stack range that, when the
deferred_at_calls calls strub_leave, is used by strub_leave itself, so it
doesn't get cleared.  sparc is quite stack hungry in this regard, and ISTM
that, if the register window doesn't get flushed, that range won't be
overwritten at all, and the copy of test_string will remain there.

If this theory is correct, this is a severe vulnerability in the stack
scrubbing implementation on sparc.  I'd envisioned overwriting some fixed stack
range after an out-of-line strub_update (hand-coded assembly tail-called from
strub_update could accomplish this), to catch just this kind of situation, but
strub_update has been so lean in stack use that this didn't seem necessary. 
Now, for sparc, this seems to be essential.

Could you please help me confirm this theory?

Since it is likely that GDB would cause register window flushes that wouldn't
occur in normal execution, inspecting the stack range would be little use, but
checking the addresses would likely confirm it.

Here's a debug session (on x86_64) that I'd appreciate if you could mirror on
sparc.  

gdb strub-defer-O1
b 32
run
p /x &s[7]
b strub.c:103
continue
p /x base
p /x end

If the theory is wrong, &s[7] will be between base and end, but if it's
correct, it will be above end, and increasing PAD enough in the testcase would
likely be enough to move the string out of the register window saving part of
__strub_leave's frame, and make this (and other tests that define PAD) pass,
confirming what we need for a proper fix.

Thanks,

Reply via email to