I understand that MTE uses TBI (Top Bit Ignore) feature from ARM, so some of the top 4 bits in a virtual memory address is used to carry the tag for the memory allocation.
But then I'm curious how does MTE catch this:
u8 arr[17];
arr[18] = 1;
arr
asks to allocate 17 bytes, but MTE is 16 byte granule, so 32 bytes would get the same tag.
So if I access arr[18]
, I think the tag should still be the same, so MTE wouldn't be able to catch this, is this correct?
Only if I access arr[32:]
, MTE would be able to catch this.
I'm not sure if this is correct, or if I'm missing something..
On top of that, OS will usually allocate memory in page granule, and I'm not sure if that will affect anything..
Yes, you are correct.
MTE is a helper, not a definitive answer. It cannot catch overflows inside the same granule.
It can also be vulnerable to tag reuse if an attacker has enough control over the program. Heap spraying and heap massaging are well known techniques that are made harder but not impossible to employ with MTE.
However, the part about the OS allocating memory in page sizes, while correct, is not relevant. The OS returns pages, yes, but the allocator (i.e. malloc
) manages this space by returning sub-page sized chunks. The whole point of an allocator is to efficiently use the pages returned by an OS (otherwise you would end up calling a syscall for every allocation and waste almost all the memory).
It's the allocator that colour the memory, not the OS (in fact, instructions like stg
are accessible in user space).