Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-id: <14A60053-301C-422E-8300-9AF56BF69F6B@apple.com>
Date: Fri, 31 Oct 2025 20:47:56 -0700
From: Oliver Hunt <oliver@...le.com>
To: Thiago Macieira <thiago@...ieira.org>
Cc: Alejandro Colomar <alx@...nel.org>, Paul Eggert <eggert@...ucla.edu>,
 libc-alpha@...rceware.org, musl@...ts.openwall.com,
 "A. Wilcox" <AWilcox@...cox-tech.com>,
 Lénárd Szolnoki <cpp@...ardszolnoki.com>,
 Collin Funk <collin.funk1@...il.com>,
 Arthur O'Dwyer <arthur.j.odwyer@...il.com>,
 Jonathan Wakely <jwakely@...hat.com>, "Paul E. McKenney" <paulmck@...nel.org>
Subject: Re: realloci(): A realloc() variant that works in-place



> On Oct 31, 2025, at 10:53 AM, Thiago Macieira <thiago@...ieira.org> wrote:
> 
> On Friday, 31 October 2025 10:31:54 Pacific Daylight Time Paul Eggert wrote:
>> On 10/31/25 11:25, Thiago Macieira wrote:
>>> I think the Committee would balk at adding a function
>>> that takes a pointer to already-freed memory whose purpose is to allow the
>>> contents of the new object to be adjusted solely based on arithmetic.
>> 
>> Do you know of any platforms where this does not in fact work? Other
>> than sanitizing platforms that go to some lengths to impose the
>> Committee's rules even though the hardware would work fine?
>> 
>> If not, then perhaps we can convince the Committee that the mismatch
>> between the current rules and reality is causing real harm, and that
>> it'd be a win for C's users to change the standard to match reality better.
> 
> Oliver, please comment on ARM64e if you can, for pointer authentication. Think 
> not just of statically-known pointers like vtables, but the general case of 
> pointer authentication.


I don’t believe ptrauth would really play into this, but MTE does.

At an _extremely_ high level you can consider MTE as providing memory access permissions at a granularity in the order of bytes - I think 16 bytes on arm.

Under MTE an allocator can ensure a previously valid pointer is simply invalid and _cannot_ be used.

Like ptrauth this is largely probabilistic, but the allocator use case folk have presented is deterministic - unallocated memory cannot be read.

Just to be clear MTE isn’t an area I’m an expert in. MTE is another “oh look there are free bits at the top of a pointer” based mitigation. While pointer authentication uses those bits to validate the value of the pointer, MTE uses those bits to protect the validity of the pointer.

MTE does this by saying the high bits of a pointer contain a tag. To protect a region of memory with MTE, to regions of memory are allocated, the region that you wish to protect, and the tag space. The protected region is divided into atoms of some number of bytes (again I think 16 bytes on ARM), giving N atoms. The tag region then consists of N tags of some number of bits, the Nth atom in the projected region corresponds to the Nth tag in that region.

When you deference a pointer the MMU tests for the existence of a tag, if a tag is present the MMU looks up the tag associated with that address. Then, if the tag does not match, it triggers a fault (in this weeks episode of “what is a trivial operation?” :D)

When the allocator (or whatever is involved) wishes to allocate from the protected region, they first do the usual allocator things needed to find the memory that will be returned. The allocator then chooses a tag - how it’s chosen entirely up to the allocator - and then sets the upper bits of the pointer to that tag, and updates the tag space such that the tags for all of the atoms covered by the allocation are set to that tag.

On freeing an object the allocator can choose to invalidate _all_ existing copies of the pointer by simply replacing the tags for the protected region. At that point any attempt to dereference those pointers will fail.

On systems with MTE, your ability to make any assumptions about how much memory can be “safely” accessed outside of a live object - ie where previously a program may have been able to get away with an OoB because the OoB was within the bounds of the size class containing their object, that may now fail.

Similarly even if the allocator has returned sequential allocations, access object n+1, through `object pointer n + sizeof(type)` may now fail.

—Oliver







Content of type "text/html" skipped

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.