C++ Logo

sg14

Advanced search

Re: Memory Safety and Page Protected Memory

From: Tiago Freire <tmiguelf_at_[hidden]>
Date: Fri, 1 Mar 2024 23:37:08 +0000
> Safe memory is special OS memory that is somewhere else, not the app's stack, not in the heap, not in static memory, at an address far away from all of the other pointers in the app. It is almost impossible that incrementing some other pointer in the app can overrun into a safe memory data buffer.

> Not only that, a second requirement is that a pointer to a safe memory data buffer is impossible to overrun. A buffer overrun by a safe memory pointer is not undefined behaviour. Increment the safe memory pointer, then access off the end of its buffer, and the app will segfault or raise a signal every time, immediately. No guard bands, it just works that way at the OS level.

1. There's no such thing as a "special type of memory that cannot be overrun into". All memory is interfaced via an address, that address is a number, and any pointer to an address can be set to anything as long as it is arithmetically possible. This is not UB nor should it be, nor does it ever cause a segfault. And you will never be able to implement a solution that detects that you are accessing data out of bounds of the originally intended pointer, not now and not ever in the future, as long as the memory is accessible somewhere to the "application/thread" it is accessible.
Segfault occurs only when you try to access it, and your hardware detects that the piece of memory is not assigned to what is currently running.

For this to have any chance of success (and I do believe that the proposal does have its merits), this must be understood.

2. The second point that must be acknowledge is that this "specialized memory" must be readable. You create it for a reason, at some point the application must be able to use it, if it couldn't read it then it might just as well not be there thus making the problem mute.

But just because a piece of memory is readable it doesn't mean that it is ALWAYS readable, and that is perhaps the key point to make this work.

On hardware that support such form of memory segmentation, it is generally operating system that manages what memory is visible to different running applications, and it can only do this while running in an elevated privileged mode that regular user applications shouldn't have access too.

Now, I'm not totally sure on the details, and correct me if I'm wrong, someone with more knowledge on how these systems work at the CPU level should be able to weigh in on this.
In theory it should be possible to ask the operating system for a piece of memory that is locked away, then implement an interface where the application could ask the operating system to unlock it momentarily for reading, you do the tasks that you need to do, and then ask the operating system to lock it away again.
And preferably "unlocking memory" should be done at the thread level (only the unlocking thread has access to it), as to avoid race conditions with other threads, and it will be the responsibility of a developer to make sure to only unlock it in "safe" parts of the code and ensure to always lock it back when no longer needed.
Now this section of memory would still be vulnerable to buffer overrun attacks while it is unlocked, and there's nothing that would stop a remote execution attack from just opening the locks, but if other threads are unable to read it, and the memory is only unlocked in a very small well control piece of code, then you could effectively frustrate any buffer overflow attacks. It reduces the attack surface (which might just be enough in many cases) but it is not perfect.

This will need operating system support, because only in privileged mode should you be able to operate the locks.

Note protecting the password wouldn't be enough, passwords are rarely ever used directly, often they are just used with hashing to generate cryptographic keys, and I hope you are not just computing the hashes and cryptographic keys on the stack or regular memory because those are still accessible, and If I can't have access to your password having access to the keys work just as well. All of that will need to be protected, all of that very easy to do wrong,... yes doable, but also trivial to mess up without even realizing it.

Received on 2024-03-01 23:37:11