This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: RFD - Support for memory tagging in GLIBC
- From: Szabolcs Nagy <Szabolcs dot Nagy at arm dot com>
- To: DJ Delorie <dj at redhat dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- Cc: nd <nd at arm dot com>, "libc-alpha at sourceware dot org" <libc-alpha at sourceware dot org>
- Date: Tue, 10 Sep 2019 14:59:23 +0000
- Subject: Re: RFD - Support for memory tagging in GLIBC
- Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IzMqjwlxe811iuxgRVJZAUrVTV+YBkjklgwgWBDK1W4=; b=m+rpwawh+zpWsjC5XNYu1AfxTBTgC5MaRsIdWDn5NyCubgqOIkF61L7z12ArdcdxOXSCnivLF0HAtxuGWle0BFbTr5L731aSoAQ0G/4GpE1hwkK844IXgLzvgb8QkHkHQp5epKHm9uQIhk4nvvK8bY4NXDp5R4EC5I3u1I/pTip+yYKY1jspGH8tEOgb5jY2v52rkZrq5qNfXVmcCEM1a5Y2HaE7KyG4dQFjuEsGVfaq8DfkTGYEwxBhgVx5ndKwE4kwCfFYcS6StSzsrvIpxMYlUC5RqNinkBcWdz+YYusPNngItc8CgmKt3pIz+jPdvIWZZhma4YarswwKzyYbMQ==
- Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Fvgg6ULiuVvd3VAEfAlotQ/brlHN6StlO+w7MaA18lLVfGQ9+31dV99yCgax8I8FGZyMNUZjW18AY6tzWsJwucR6Jr4rGaI3xE/4qSTRs6GdsFHeT+Hmj6GWdu86vkjM/mgT6zOC0rAJ3tCoCO26imdOgCOKPkCaNaPH0WaoNBVhQ15KGqjHemRIyGWLIPVI4t/bORjSp7i7mejGmuXx//tyaQRxfo0duwajUdPANMY3eI/mJ2pNMF/o01/3w/Tfm4fwNeepCr/zn5qDP/K7BCL7/aoZZxwvggWkimkBUoYtV+4EoIxYv7Ey3UYeJvGNzevZAgrvpefk8SMpsW7WpQ==
- Original-authentication-results: spf=none (sender IP is ) smtp.mailfrom=Szabolcs dot Nagy at arm dot com;
- References: <xnftl5i8tc.fsf@greed.delorie.com>
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.