37 comments

[ 4.8 ms ] story [ 57.5 ms ] thread
Sparse on details.

Presumably will be based on the existing Linear Address Masking/Upper Address Ignore specs, which are equivalent, and will be similar to CHERI.

If so it needs to be opt-in or at least opt-out per process, because many language runtimes use these pointers bits to optimize dynamic types, and would suffer a big performance hit if they were unable to use them.

Not a whole lot of language runtimes (if any) really depend on upper address ignore.

AFAIK, AMD only added it in Zen4.

You don't need the hardware UAI/LAM to make use of the high pointer bits. The most common technique is to use `shl reg, 16; sar reg, 16`, which will shift in ones or zeros from the left depending on the 47th bit.

Several runtimes use high bits tagging combined with NaN-boxing, and have been doing so since before LAM/UAI existed.

Dynamic types have classically used the lower bits freed by alignment constraints. If I know a cons cell is 16 bytes then I can use the low 4 bits of an address to store enough type info to disambiguate.
There's a technique known as "NaN boxing" which exploits the fact double precision floats allow you to store almost 52 bits of extra data in what would otherwise be NaNs.

If you assume the top 16 bits of a pointer are unused[1], you can fit a pointer in there. This lets you store a pointer or a full double by-value (and still have tag bits left for other types!).

Last I checked LuaJIT and WebKit both still used this to represent their values.

[1] On amd64 they actually need to be sort of "sign extended" so require some fixup once extracted.

There's numerous techniques used. Many are covered in Gudeman's 1993 paper "Representing Type Information in Dynamically Typed Languages"[1], which includes low-bits tagging, high-bits tagging, and NaN-boxing.

The high bits let us tag more types, and can be used in conjunction with low bits tagging. Eg, we might use the low bits for GC marking.

[1]:https://web.archive.org/web/20170705085007/ftp://ftp.cs.indi...

I highly doubt this is anything like CHERI. More likely it's their version of ARM MTE.
Doesn't CHERI use additional bits to store the capabilities rather than masking existing bits in the pointer?

But that can be problematic for any code that assumes that the size of pointers is the same as size_t/usize.

I don't see how this could not be opt in for backwards compatibility though, since existing code wouldn't use the new instructions.

I would not assume they just use bits in the address word for the tag.

LPDDR6 includes 16 bits of host-defined metadata per 256 bits of data. Systems can use that for ECC, and/or for other purposes, including things like tagging memory. DDR6 will likely include a similar mechanism.

SECDED ECC requires 10 bits, leaving you 6 bits. That's enough for one bit per aligned address word, which is probably used to denote "valid pointer" like CHERI.

I wonder what happened that Apple/ARM has implemented something similar at nearly the same time. https://security.apple.com/blog/memory-integrity-enforcement...
I hope there are OS level (ie kernel build options) to turn this kind of thing off or just ignore the 'tags'. I know it's important for corporate use cases and monetary transactions and all that, but on my personal computer I use for fun I want to be able to peek and poke.
If you're worried that this is going to prevent you from peeking and poking, I think you're mistaken. This is to protect a process against itself, not the outside. It will also likely be a single bit flip away of being unenforced at runtime, as most x86 protections already are to be to make debugging tools feasible.

By the way, there are already systems in place to prevent you from accessing certain memory zones. Yes, even on Linux, it's possible to make memory regions inaccessible even to root or the kernel itself. The time to be worried about that was 10 years ago.

Is there a whitepaper or ISA manual change describing the feature?
It’s just probabilistic memory safety, at best

Still cool, but not a replacement for memory safety language implementations.

Memory coloring (what is to my knowledge being proposed) is certainly probabilistic however it really does a lot towards memory hardening more than memory safety. It makes successfully pulling off ROPs, etc far harder.

Even if you are using a memory safe language, memory bugs still pop up in various places (cough FFI & ABI cough) so this is a massive step in the right direction towards blocking attacks even when the developers have done "all the right things" short of formally verifying their stack from top to bottom (and even then).

I've been meaning to ask you what the motivation of your project is? Why would you want a safe-c? When I saw the headline I was worried that all my runtime code would break (or get slower) because I do some very unsafe things (I have a runtime that I compile with -nostdlib)

I'm also tempted to write a commercial C++ compiler, but it feels like a big ask, paying for a compiler sounds ridiculous even if it reduces your compile time by 50x

Garbage article.

Like, cool, you guys are starting to talk about a new instruction set that will make C safe somehow. Yet you failed provide an ounce of detail for how you'll accomplish that.

This might as well been a "And we'll make our CPUs 10x faster and they'll use 10x less power!". Or "Future CPUs will have a 10ghz clock speed!"

Again, who is this article for? The government maybe to assure them that x86 will take cyber security seriously?

[flagged]
I mean, sandboxing AI agents once they get smarter is a valid concern (if not a major future concern).
Now they just need to agree to implement ECC everywhere instead of using it as a product differentiator, so we can reduce the amount of random issues caused by memory and bus errors.
With all the negative comments here: This is existing technology on ARM64 (MTE) and on modern iPhones (https://security.apple.com/blog/memory-integrity-enforcement...).

For a good intuition why this (coupled with instrumenting all allocators accordingly) is a game-changer for exploitation, check https://docs.google.com/presentation/d/1V_4ZO9fFOO1PZQTNODu2...

In general, having this come to x86 is long-overdue and very welcome.

But wait, how do you know that's what this is?

The reason I'm negative is the entire article has zero detail on WTF this instruction set is or does. The best you can do is guess from the name of the instruction set.

Compare the linked iPhone article to this blog and you'll quickly see the difference. There's very real discussion in the MTE article of how the instructions work and what they do. This article just says "Memory safety is hard and we'll fix it with these new instructions that fix memory safety!"

Is there a comparison of memory tagging designs for different architectures (POWER, SPARC, CHERI/Morello, Arm MTE/eMTE, Apple MIE, x86, RISC-V)? e.g. enforcement role of compiler vs. hardware, opt-in vs mandatory, hardware isolation of memory tags, performance impact, level of OS integration?
Wow that weird state machine doc is great! Thanks for sharing.

I’m lukewarm on this.

- It is long overdue and welcome.

- It won’t stop a sufficiently determined attacker because its probabilistic and too easy to only apply partially

Is this good? Yes. Does it solve memory safety? No. But does it change the economics? Yes.

Looks like this is in response to the Apple paper from a couple of weeks ago about memory tagging. Excellent news even if this wasn't pushed along by Apple.
fwiw "knee-jerk reaction to Apple MIE" is not exactly the right characterization of this. MPX existed and faded away, and it's not very surprising that x86-world would wait for someone else to try shipping hardware support for memory safety features before trying again.
I wouldn't say that's fair. MPX failed because it was a very problematic solution to this problem.

MPX had a large (greater than 15-20%) overhead and was brittle. It didn't play well with other x86 instructions and the developer experience was extremely poor (common C and C++ design patterns would cause memory faults with MPX).

Apple MIE (which is essentially ARM MTE v2) and MTE on the other hand have near invisible levels of overhead (~5-10%) with the ability to alternate between synchronous and asynchronous tracing of faults where the latter has a much lower overhead than the former (allowing you to check in production for very little overhead and get better debugging in test). They also work essentially seamlessly with the rest of the ARM ecosystem and it takes very little to integrate the functionality into any language ecosystem or toolchain.

If MPX was comparable with MTE, it certainly would have gotten the adoption that MTE is getting but the "tech" just wasn't there to justify it's use.

It's ok the C committee will make sure to fumble this up even with HW support
It seems very strange to me to finally get around to this right as we are finally getting low level software that no longer needs it (and we've had high level software that doesn't need it for ages). At this point I think I'd prefer the transistor budget and bits of memory were spent on other things.
The article seems sparse on details.

Would this imply an architecture similar to what Lisp-Machines once had ? That'd be a great addition IMO, and would speed up a lot of dynamic-ish languages without resorting to unsafe-routes for speed.

They should standardize what's going on in Intel ME and AMD PSP (they won't since both are backdoors.)
To bring Corporate Authoritarianism to x86...

It's scary how much of the population will suddenly shut off their brains whenever "safety and security" or similar phrases are mentioned.

It would be nice to know how this memory safety instructions should be used by software developers. Assuming I write C++ code, what should I do? Enable some new compiler flags? Use special runtime library? Use some special variant of the language standard library which uses these new instructions? Completely rewrite my code to make it safe?