C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Standardising 0xdeadbeef for pointers

From: Thiago Macieira <thiago_at_[hidden]>
Date: Sat, 02 Aug 2025 17:02:19 -0700
On Saturday, 2 August 2025 15:27:07 Pacific Daylight Time Oliver Hunt wrote:
> I was also unsure about whether the info you get from that source allows you
> to distinguish “mapped” from “mapped and readable”, “mapped and writable”?
> It sounds like you have more familiarity with doing such queries (for my
> work I only ever need the darwin “is this permanently readonly” check for
> root of trust checks).

On Linux, /proc/self/maps does provide the protection flags of the memory in
question, so you'd know if it is readable, writable, executable, shared or
private, and if it came from a file. On Windows, I think VirtualQuery() also
gives the protection flags. On other OSes, I haven't seen that. TBH, I haven't
seriously looked, because aside from curiosity and some light debugging, the
information isn't useful for applications at runtime. As I said, it can change
at a moment's notice in a multithreaded application -- and I work on a
library, so I have to assume there are other threads running. I have enough
headache dealing with thread-safety while staying withing the boundaries of
POSIX API, I don't need to buy myself *more* trouble.

I also forgot one more detail: mapped memory does not mean *committed* memory.
You may still end up in an OOM Kill because the OS can't allocate the memory
you need.

> > Therefore, this is a TOCTOU problem. There's no reliable way to get the
> > correct information cross-platform and there's no way make it reliable to
> > use. And this was in no way what the OP was asking for.
>
> It is also possible to have an access be valid on one thread but not on
> another, so if you tried to use/cache a query on one thread and then reuse
> it on another it may fail, even if you are doing it immediately.

That's not supposed to happen. Unless the application is using some exotic OS
primitives, the memory protections apply application-wide to all threads. It's
in fact one of the things that defines what "threads of an application" are:
they all share the same VM space, along with the file descriptor/handle table
and a few other odds and ends. If you are doing such a thing (like using the
clone(2) system call on Linux with a weird set of CLONE_* flags), you had
better know what you're doing. C++ will not protect you, nor will the
processor or the OS. It would be unreasonable to ask the Standard for a
function to work properly under those conditions.

It's similar to asking for non-standard memory/cache behaviour, such as
uncachable or write-combining on x86, or enabling alignment-protection flags in
processors that support them, if the compiler isn't prepared to generate code
obeying those rules.

You asked for the rope and the gun, make sure you use them correctly.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Principal Engineer - Intel Platform & System Engineering

Received on 2025-08-03 00:02:23