C++ Logo


Advanced search

Re: Memory Safety and Page Protected Memory - Stack Swapping

From: Robin Rowe <robin.rowe_at_[hidden]>
Date: Sat, 2 Mar 2024 16:35:49 -0800
On 3/2/2024 1:54 PM, Tiago Freire wrote:
> And I have come up with the idea of stack swapping...

Interesting. I believe each thread has its own stack already. On
Windows, Linux and MacOS, any thread switch is also a stack switch.

> could be a protected page locked to the current thread (i.e. only
> that thread can read it).

Yes, it's already that way sort of...

Each thread has its own stack, so the pointer to a protected page is
away from the stacks of other threads. It seems almost impossible that
another thread could find the protected page pointer in some other
thread stack. If a rogue thread could find the pointer somehow,
protected page access is at the process level, so not blocking per thread.

Recall that the point of allocating a protected page was to harden the
popular security hole of nearby buffer overruns during password
authentication or other sensitive data memory, not a general solution.

> If you have a separate application who’s only responsibility is
> to manage the secrets...

A concern running a separate process is that IPC may create more
opportunity for security holes than was gained by putting key management
in a separate process. A hacker will try to replace the key manager
process/app or may man-in-the-middle attack the comms channel that tells
apps a login is verified.

On Linux we have libpam.so, which is not in a separate process.

Robin Rowe
Beverly Hills, California
*Chairman ISO WG21 SG14 C++ Banking and Financial Systems Subcommittee

On 3/2/2024 1:54 PM, Tiago Freire wrote:
> I have to admit that at the beginning I was a bit skeptical in terms of
> what was being asked was either achievable or usable.
> However, I did some further thinking on the issue and how to combine
> certain concepts to make something useful.
> 1.
> And I have come up with the idea of stack swapping, i.e. mid execution a
> thread can swap its stack for another, given that this “another” could
> be a protected page locked to the current thread (i.e. only that thread
> can read it).
> Assuming that restricting pages to specific threads is possible.
> The idea being that access can never be changed. When the application
> needs to do something sensitive, it will swap its stack to this special
> protected one, do all of its cryptography there, return, swap the stack
> back, zero out the special stack before returning it to the system.
> You could even use existing cryptographic libraries to keep it safe as
> long as they do everything on the stack, they wouldn’t be able to tell
> that they were running on a special stack. If they happen to require
> heap allocation then that will of course be leakable, but you can fix
> that by providing a special allocator where the pages are locked to the
> running thread.
> As long as this part of the code is done correctly (which can be made to
> have a small testable surface), this kind of system would be
> invulnerable to overflow attacks. And even if you managed to get remote
> execution to work on some other part of the code you may not get that
> far, as there would be no facility available to unlock the page assigned
> to another thread, unless you can:
> a) swap the running context of the thread that currently has privileged
> access to the memory at the right time. This is a higher bar to achieve.
> b) get a root kit to gain the OS privileged access. At that point the
> entire system is screwed, and this type of protection wouldn’t make much
> of a difference.
> As a bonus point, if you happen to leak this privileged memory, the
> system would be able to reclaim it back when the thread exits, or with a
> facility specially crafted to clear it.
> This wouldn’t need to affect code generation of current applications
> given that you would need to explicitly opt-in by using special functions.
> 2.
> Messing with code generation isn’t a bad idea, specially if we are
> dealing with open-source applications. I can envision an additional
> argument being passed to the compiler in order to randomize the layout
> of where certain functions or variables are relative to each other, or
> change other aspects of the resulting code to add additional fuzzing.
> The side effect of which would be, even if someone managed to replicate
> the exact build environment, and figure out the exact version of the
> application that is running, and they have an exploit where they could
> target a specific place in memory, they wouldn’t have access to the
> exact build and would be much harder to figure out the code layout to
> make the exploit work.
> Sure, this will have some impact on the predictability of the run time
> performance because of how the instruction appear in cache, but if what
> you are trying to do is protect data, predictable performance is not as
> high a priority.
> 3.
> There’s always the lose point of how the cryptographic keys/credit card
> secrets end up in the application to begin with. As James hinted at, it
> seems like a bad idea that the user facing application that is subject
> to attacks and exploits from external malicious actors is also the
> application that has direct access to your passwords. If you have a
> separate application who’s only responsibility is to manage the secrets,
> and it can do it right, then the issue isn’t as much of a problem, this
> is not to say that this sort of memory protection isn’t useful, and
> protecting your one-time usable tokens isn’t worth doing, but perhaps
> may be less important if better security practices were adopted instead.
> There’s no magic solution that can save anyone if the developer just
> does “stupid shit”, and a minimum level of competence is required.
> And I’m not sure if adopting better security standards is more productive.
> In summary.
> In any case it seems to me there is indeed a great deal of something
> that can actually be done, and definitely worth researching. But most of
> it involves either hardware or operating system design, this could
> benefit all programming languages that can be compiled into byte code,
> not just C++. The role of C++ would only be to standardize the API’s to
> make it available to the user. *But these facilities will need to be
> created first outside of the C++ standard before the committee could do
> anything about it.*
> It is an interesting point of discussion; somebody should do research on
> this topic; maybe it will become standard practice in the future. But
> the C++ committee may not be the right venue.
> Br,

Received on 2024-03-03 00:35:51