C++ Logo

sg14

Advanced search

Re: Memory Safety and Page Protected Memory

From: Robin Rowe <robin.rowe_at_[hidden]>
Date: Thu, 29 Feb 2024 09:25:01 -0800
David,

> In particular, do platforms (esp MSVC or GCC/Clang)
> provide this capability somehow?

Yes, with existing but obscure POSIX and Windows APIs called in a
specific way. It would be nice if there was an obvious standard call,
such as memory_safe_alloc(), that does the trick.

Page protection is already implemented at the hardware level by Intel,
or whoever is the chip maker. We all expect to be memory safe across
apps, and seem to accept that it's better to suffer debugging annoying
segfaults than having undefined behavior that creates a security hole
across apps.

Each app on a modern OS is already running in its own page-protected
memory. It has never been the practice to use page protection within an
app to protect sensitive data against our own app's wild pointers.
That's what I'm suggesting that's new.

> Normative wording. The C standard says nothing about guard pages,
> so you can't use that technique to explain how your
> memory_safe_malloc() works.

Page protected memory has no guard pages. Step off the end, and poof!
Segfault.

> submit a proposal to WG14.

Yes. Step one was asking if anyone besides me thinks it a good idea.
Seems some like it. Step two is I'll create an implementation
programmers can test. Step three I'll write a proposal to make it
standard. Discussing with you and others here has helped me understand
what I need to write. Thank you!

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

On 2/29/2024 5:13 AM, David Svoboda wrote:
> Robin:
>
> OK. If you can propose a memory_safe_malloc(), then you'll have to
> submit a proposal to WG14. The proposal should include:
>
> Related work: In particular, do platforms (esp MSVC or GCC/Clang)
> provide this capability somehow? That is, are you inventing a new
> function, or are you standardizing existing practice?
>
> Normative wording. The C standard says nothing about guard pages, so you
> can't use that technique to explain how your memory_safe_malloc() works.
> You could say "the technology is up to the platform", but you then have
> to make guarantees, such as "accessing memory outside the bounds of this
> chunk always trap". Something more specific than undefined behavior
> (which is what exceeding malloc() chunks gets you). You would also
> have to handle *far away* access, such as memory_safe_malloc(8) +
> 1000000...I don't think guard pages will buy you that.
>
> You could always implement fat pointers (there are pre-existing research
> work), but they will be incompatible with C's current pointers.
>
> Finally, I agree that rewriting lots of code in Rust is expensive. But I
> suspect that headaches we've incurred in non-memory-safe C for the last
> 50 years is even more expensive :/
>
> --
>
> David Svoboda <svoboda_at_[hidden]>
>
> Software Security Engineer
>
> CERT Secure Coding Initiative
>
> (412) 596-0401
>
> *From: *Robin Rowe <robin.rowe_at_[hidden]>
> *Date: *Thursday, February 29, 2024 at 4:25 AM
> *To: *David Svoboda <svoboda_at_[hidden]>,
> undefined-behavior-study-group_at_[hidden]
> <undefined-behavior-study-group_at_[hidden]>, sg14_at_[hidden]
> <sg14_at_[hidden]>
> *Subject: *Re: Memory Safety and Page Protected Memory
>
> Warning: External Sender - do not click links or open attachments unless
> you recognize the sender and know the content is safe.
>
>
> David,
>
> > In one case, you have legacy code, perhaps without source, where you'd
> > like to prevent out-of-bounds reads/writes to all chunks returned by
> > malloc(). This is what ElectricFence does.
>
> No, I'm not suggesting a general replacement for malloc().
>
> > At the time, my need for dynamic analysis for memory safety became
> > more satisfied with Valgrind, which provided the same safety
> > features without using guard pages.
>
> No, I'm not suggesting replacing valgrind.
>
> > In the other, you'd like to protect specific chunks of memory, rather
> > than all memory, by replacing malloc() with a (currently non-standard)
> > memory_safe_alloc() function.
>
> Yes, that is what I'm suggesting.
>
> > My question to you is: wouldn't Valgrind (or a more modern
> > analogue like UBSan) be sufficient to handle this use case?
>
> No, it's not sufficient. I want extra protection for sensitive data. I
> don't want to rely on faith that programmers have been careful or have
> used valgrind and static code checkers.
>
> > I know of no memory_safe_alloc() function...you would think it
> > would have been provided by glibc() or some other platform-specific
> > library.
>
> Yes, that is the small hole I'm trying to fill.
>
> Linux and Windows memory safe allocation APIs exist, but nothing
> portable. It takes having an interest in how memory protection works in
> operating systems to even be aware that page protection is a thing. That
> there exists page protected memory, a fourth type of memory programmers
> may allocate (besides stack, static and heap) is not taught in any
> typcial computer science class.
>
> It's important now because the DoD and other major sponsors of software
> development are recommending to stop writing C/C++ code, or to rewrite
> C/C++ legacy code, using instead languages that call themselves memory
> safe, such as Rust. As often happens, C/C++ is more versatile than
> detractors expect, and can be memory safe, at least to the extent of
> protecting sensitive data.
>
> I've never seen a memory safe C/C++ pointer in legacy code, nor used one
> in the decades I've been programming in C/C++. I became interested in
> memory safety when I chaired the Motion Picture Academy Rust committee.
> Rust evangelists say we should all want memory safety. But, I didn't
> love Rust enough to want to abandon C/C++. I got thinking, does it have
> to be Rust? Does having memory safe pointers matter everywhere, or only
> for sensitive data?
>
> There's a performance cost allocating memory safe pointers that seems to
> make them unsuitable for general use in C/C++, but programmers could
> harden C/C++ code where it matters most with memory safe pointers. Much
> easier than rewriting everything in Rust.
>
> Robin Rowe
> Beverly Hills, California
> *Chairman ISO WG21 SG14 C++ Banking and Financial Systems Subcommittee
>
> On 2/28/2024 11:39 PM, David Svoboda wrote:
>> Robin:
>>
>> It sounds like you are suggesting a new use case:
>>
>> In one case, you have legacy code, perhaps without source, where you'd
>> like to prevent out-of-bounds reads/writes to all chunks returned by
>> malloc(). This is what ElectricFence does. While it was useful, I did
>> not follow whatever became of ElectricFence, or its general technology.
>> At the time, my need for dynamic analysis for memory safety became more
>> satisfied with Valgrind, which provided the same safety features without
>> using guard pages.
>>
>> In the other, you'd like to protect specific chunks of memory, rather
>> than all memory, by replacing malloc() with a (currently non-standard)
>> memory_safe_alloc() function. This may be easy enough to do on legacy
>> source code. It's a fair enough idea, although I know of no
>> memory_safe_alloc() function...you would think it would have been
>> provided by glibc() or some other platform-specific library. My
>> question to you is: wouldn't Valgrind (or a more modern analogue like
>> UBSan) be sufficient to handle this use case?
>>
>> --
>>
>> David Svoboda <svoboda_at_[hidden]>
>>
>> Software Security Engineer
>>
>> CERT Secure Coding Initiative
>>
>> (412) 596-0401
>>
>

Received on 2024-03-01 19:50:21