Live data from Hacker News

Memory Tagging and how it improves C/C++ memory safety

arxiv.org

11–20 of 41 posts

Re: Memory Tagging and how it improves C/C++ memory safety

#11
post #9

A long time ago I found some memory problems in a C++ codebase we had inherited and that crashes from time. In Windows you can protect memory blocks with a function call so I overloaded new and malloc and added some protected blocks before and after the actual memory. Then we ran the code for a lot and it would fault right at the point of the memory overwrite instead of some place later. It made the code very slow bu…

On illumos you can use libumem to replace malloc() via LD_PRELOAD, and then you can instruct it to do the same thing via the UMEM_DEBUG environment variable. It's a fantastic technique for catching these issues without completely destroying application performance.

See also: https://illumos.org/man/umem_debug

Re: Memory Tagging and how it improves C/C++ memory safety

#12
post #9

A long time ago I found some memory problems in a C++ codebase we had inherited and that crashes from time. In Windows you can protect memory blocks with a function call so I overloaded new and malloc and added some protected blocks before and after the actual memory. Then we ran the code for a lot and it would fault right at the point of the memory overwrite instead of some place later. It made the code very slow bu…

These days the gcc and clang memory/address sanitizers can do this quite nicely, and they tend to have low overhead as well (in my limited experience so far).

Re: Memory Tagging and how it improves C/C++ memory safety

#13
post #7

This somewhat reminds me of the Microsoft debugger convention of initializing memory with various tags so that when you crash with a pointer bug, you can tell what kind of memory was trod upon. They even made the hex codes semi-mnemonic so it was easier to remember, e.g., 0xCD=clean, 0xDD=dead, 0xFD=fence, etc. https://stackoverflow.com/a/370362/1424242 Interesting note that with this method in the paper, "Temporal a…

> I read the paper's description, and still don't quite understand exactly what they mean by "memory safety". This is not referring to safer programming practices like using the STL with iterators, correct?

I would assume it's referring to some kind of actual guarantee, which STL doesn't provide even in idiomatic use, due to things like iterator invalidation or subtly broken use of references.

Re: Memory Tagging and how it improves C/C++ memory safety

#14
post #9

A long time ago I found some memory problems in a C++ codebase we had inherited and that crashes from time. In Windows you can protect memory blocks with a function call so I overloaded new and malloc and added some protected blocks before and after the actual memory. Then we ran the code for a lot and it would fault right at the point of the memory overwrite instead of some place later. It made the code very slow bu…

These days the gcc and clang memory/address sanitizers can do this quite nicely, and they tend to have low overhead as well (in my limited experience so far).

ASan has lower overhead than Valgrind, and is great when you cross-compile something to an embedded/constrained system. I have however observed noticeable overhead on code doing many small allocations.

Which was nice to be able to observe, because the code didn't need to do many small allocations.

Re: Memory Tagging and how it improves C/C++ memory safety

#15
post #8
post #7

This somewhat reminds me of the Microsoft debugger convention of initializing memory with various tags so that when you crash with a pointer bug, you can tell what kind of memory was trod upon. They even made the hex codes semi-mnemonic so it was easier to remember, e.g., 0xCD=clean, 0xDD=dead, 0xFD=fence, etc. https://stackoverflow.com/a/370362/1424242 Interesting note that with this method in the paper, "Temporal a…

> This somewhat reminds me of the Microsoft debugger convention of initializing memory with various tags so that when you crash with a pointer bug, you can tell what kind of memory was trod upon. They even made the hex codes semi-mnemonic so it was easier to remember, e.g., 0xCD=clean, 0xDD=dead, 0xFD=fence, etc. BSD's malloc.conf framework does something similar. Though they've managed to be incompatible with one an…

.. and on glibc (the usual libc on Linux), the MALLOC_PERTURB_ environment variable can be used for similar stuff (http://man7.org/linux/man-pages/man3/mallopt.3.html ).

Re: Memory Tagging and how it improves C/C++ memory safety

#16

Does anyone know how this relates to what the Burroughs B5500 and B6500 operated?

This is very similar to the Burroughs approach that later influenced Multics and the lispm architectures (and is available in some RISC-V versions). Notably Intel used this in the unfortunate iapx 432 and cleverly built some of this approach in their segmented memory model).

However by the late 1970s it had been figured out that you could do some of these tricks without dedicated hardware support (mask-boxing of integers, for example on processors that ignored unaligned access you could use the least significant bits for tagging; on ones with address spaces less than the word length you could often do the same with the upper bits). These bits could be used by GC and/or for fast type systems, and by the mid 1980s had pretty much wiped out the advantage of dedicated hardware for Lisp implementations (the lispms started out much faster at tag manipulation but the weight of work on the general purpose machines caused the latter to get better (and cheaper) much faster).

The bigger advantage of hardware support IMHO is the security opportunity for capability management.

Re: Memory Tagging and how it improves C/C++ memory safety

#17
post #2

Am I correct in thinking that this is a similar idea to page faults but per allocation rather than per process?

After skimming the paper, I think it's actually closer to segmentation. They just split the address space into X number of segments. The allocator then ensures every allocation lies completely within one of these segments and attaches that segment's ID to the returned pointer. Fundamentally, paging and segmentation are fairly similar though, so you're not wrong, there is just no concept of a 'page-table' here. That s…

> After skimming the paper, I think it's actually closer to segmentation. They just split the address space into X number of segments. The allocator then ensures every allocation lies completely within one of these segments and attaches that segment's ID to the returned pointer.

It's sort of the other way around. Replacing "tags" with "colors" since somehow it seems a bit more intuitive, the allocator itself just "colors" different allocations with a different color, rather than splitting up the address space beforehand. The returned pointers are also colored and a fault occurs if any pointer is used to access memory of a different color.

> Obviously, that doesn't even cover a full 4K page of data. So I presume the segments must repeat.

Definitely - every color will be used many times, so they only probabilistically catch any fault, based on mostly the total number of colors (as long as the colors were randomized from run to run it seems like any fault would be quickly caught with a high probability). They mention in in the paper improvements such as ensuring that adjacent regions always have different colors so that linear overruns are caught with 100% probability.

> I would assume objects larger then 64 bytes would have to be untagged, since normally you would access them via offsetting from the same base pointer, and that base pointer would always have the same tag.

Not at all. The 64-bytes is only the granularity of the colors (actually they suggest 16 bytes is a better option): but an arbitrarily large region can have the same color.

Most of the rest of your post follows I think from that misunderstanding: there is no need to change the color every 16 or 64 bytes (they call this quantity TG) - you color the whole region with the same color. The TG value is just the granularity at which it can change, so it's a tradeoff between overhead for small allocations (favoring smaller TG) and total tag storage cost (favoring larger TG).

Re: Memory Tagging and how it improves C/C++ memory safety

#18
post #7

This somewhat reminds me of the Microsoft debugger convention of initializing memory with various tags so that when you crash with a pointer bug, you can tell what kind of memory was trod upon. They even made the hex codes semi-mnemonic so it was easier to remember, e.g., 0xCD=clean, 0xDD=dead, 0xFD=fence, etc. https://stackoverflow.com/a/370362/1424242 Interesting note that with this method in the paper, "Temporal a…

> I read the paper's description, and still don't quite understand exactly what they mean by "memory safety". This is not referring to safer programming practices like using the STL with iterators, correct?

Memory safety generally refers to treating each region of memory as it's expected type, not over-writing or over-reading the bounds of allocated region, not reading unitialized or freed memory, and so on.

It's a correctness problem that often ends up in the news since it's usually unchecked in C and C++ meaning that errors of that type don't necessarily result in predictable exceptions or process termination, but rather all sorts of exciting exploits.

Many higher-level languages have no similar memory safety issue (absent bugs in their implementations) since they exclude features that could result in the above problems, and include explicit runtime checks in places where the compiler or runtime cannot prove that an access is safe.

Re: Memory Tagging and how it improves C/C++ memory safety

#19
Here's related work for those interested in the subject. Two old ones:

Burroughs Architecture https://www.smecc.org/The%20Architecture%20%20of%20the%20Bur...

Capability-based Computer Systems (book) https://homes.cs.washington.edu/~levy/capabook/

Some new ones using a range of techniques:

SAFE Architecture http://www.crash-safe.org/papers.html

CHERI Architecture http://www.cl.cam.ac.uk/research/security/ctsrd/cheri/

Note: CHERI runs a modified version of FreeBSD on a FPGA board. Quite practical if it can handle that!

Watchdog Architecture https://www.cs.rutgers.edu/~santosh.nagarakatte/softbound/

Hardware-assisted Secure Allocator http://jin.ece.ufl.edu/papers/HASP17.pdf

Re: Memory Tagging and how it improves C/C++ memory safety

#20

Earlier quoted context omitted.

After skimming the paper, I think it's actually closer to segmentation. They just split the address space into X number of segments. The allocator then ensures every allocation lies completely within one of these segments and attaches that segment's ID to the returned pointer. Fundamentally, paging and segmentation are fairly similar though, so you're not wrong, there is just no concept of a 'page-table' here. That s…

> After skimming the paper, I think it's actually closer to segmentation. They just split the address space into X number of segments. The allocator then ensures every allocation lies completely within one of these segments and attaches that segment's ID to the returned pointer. It's sort of the other way around. Replacing "tags" with "colors" since somehow it seems a bit more intuitive, the allocator itself just "co…

Reading it again, I guess I missed the "shadow memory" concept they talked about, but they only mention it 5 times and none of those mentions are in the actually explanation of how they do the memory tagging. They do mention it one more time in the AArch64 implementation though, so it does look like you're correct on this. I don't understand why they didn't really make this detail much more clear though, since like you've pointed out it changes a lot about how things work.

Now, if that is the case it complicates the setup a fair amount, since now you do need a global 'page-table' like structure holding this information that the allocator configures. And from reading the paper, don't they intended for the kernel to do this checking as well on userspace pointers, indicating the kernel also needs access to this information? It's doable, and better overall, but more complicated.

Post reply on HN