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


"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.

> 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?

> - 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?

> +/* 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?


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