This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFD - Support for memory tagging in GLIBC


On 09/09/2019 20:11, DJ Delorie wrote:
> "Richard Earnshaw (lists)" <Richard.Earnshaw@arm.com> writes:
>> I'm posting this now before the Cauldron so hopefully we can have some 
>> useful discussions on the matter during that.
> 
> Given the long list of glibc topics, perhaps we could grab an empty room
> at some point for this one?  It's a bit more focused than the glibc bof.
> Else we're down to about 3 minutes per topic ;-)
> 
>> Unused bits in the top byte of a 64-bit address pointer
> 
> I wonder if we could generically abuse these bits on other architectures
> as well, but as a no-op?  It might require some platform-independent
> kernel interface to say "I want my address space to ignore the top four
> bits please".  I don't know what source-level checks or optimizations we
> could do here, but having a few more bits in the chunk header could be
> useful.

aarch64 has "top byte ignore" architecturally.
i don't think it works without arch support,
trapping every load/store would be very slow.

> 
>> can then be set to describe the colour expected at that address and a
>> protection fault can be raised if there is then a mismatch.
> 
> /me is looking forward to SIGPURPLE and SIGGREEN.
> 
>> Nomenclature: The AArch64 extension is called MTE.  I've tried to use 
>> the term 'memory tagging' (mtag) in the generic code to keep the layers 
>> separate.  Ideally mtag can be used on multiple architectures.
> 
> Just so I understand - the pointer's top four bits are compared to a
> *hidden* set of four bits per-memory-qword.  Setting the pointer's bits
> is just math, but there's some arch-specific way to tag the memory
> itself?

yes.

(there are instructions to set the color of a qword)

> 
>> - for realloc I've chosen to recolour all affected memory even if the 
>> same logical address is returned (the pointer will contain a different 
>> colour, ensuring that before-and-after pointers will not compare equal). 
> 
> We could conditional this on one of the mcheck states.
> 
>> - free() recolours the memory; this is a run-time overhead but is useful 
>> for catching use-after-free accesses.
> 
> Likewise here.
> 
>> +/* When using tagged memory, we cannot share the end of the user block
>> +   with the header for the next chunk,
> 
> This is going to cause alarm; it's a HUGE relative overhead on the
> common small allocations, and will likely bloat RSS use.  Allocations up
> to 24 bytes use the smallest (32-byte) span, if we have to bump it one
> we'd have those go to 48-byte spans, a 50% increase in RSS, or limit
> smallest allocations to 16 bytes.
> 
> Perhaps a free'd block could be recolored for internal use only, and the
> end chunk recolored appropriately?  That would retain our current
> allocation sizes and also protect against some use-after-free cases.
> It would also stop glibc from accessing not-freed memory as a chunk ptr.
> 
>> +	((mchunkptr)__libc_mtag_address_get_tag (((char*)(mem) - 2*SIZE_SZ)))
> 
> to me, "get tag" should return the 4-bit tag, not a pointer-thats-tagged
> or a pointer-without-tag.  Bikeshedding, but names are important for
> future understanding.
> 
>> +#ifdef _LIBC_MTAG
>> +  /* Quickly check that the freed pointer matches the tag for the memory.
>> +     This gives a useful double-free detection.  */
>> +  *(volatile char *)mem;
>> +#endif
> 
> I worry about how gcc will diagnose this in the future...
> 
>> +/* Non-zero if memory obtained via morecore (sbrk) is not tagged.  */
>> +#define __MTAG_SBRK_UNTAGGED 0
> 
> Is one of the 16 colors reserved for "untagged" somehow?

0 is not reserved, it's a valid color, but
if tagging is disabled valid pointers have
the tag bits set to 0, if you read the color
of a memory range where tagging is disabled
you get 0 etc.

so color 0 either means tagged with 0, or
untagged.

> 
>> +/* Set the tags for a region of memory, which must have size and alignment
>> +   that are multiples of __MTAG_GRANULE_SIZE.  Size cannot be zero.
>> +   void *__libc_mtag_tag_region (const void *, size_t)  */
>> +void *__libc_mtag_tag_region (void *, size_t);
> 
> Copies tag from pointer to memory
> 
>> +/* Optimized equivalent to __libc_mtag_tag_region followed by memset.  */
>> +void *__libc_mtag_memset_with_tag(void *, int, size_t);
> 
> Same, with memset.
> 
>> +/* Convert address P to a pointer that is tagged correctly for that
>> +   location.
>> +   void *__libc_mtag_address_get_tag (void*)  */
>> +void *__libc_mtag_address_get_tag(void *);
> 
> Copies tag from memory to pointer.
> 
>> +/* Assign a new (random) tag to a pointer P (does not adjust the tag on
>> +   the memory addressed).
>> +   void *__libc_mtag_new_tag (void*)  */
>> +void *__libc_mtag_new_tag(void *);
> 
> Create new tag.  Does this have a way of skipping reserved colors?
 the architecture allows excluding tags
when generating random tags.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]