|
|
Message-ID: <20260513133508.GB3520958@port70.net>
Date: Wed, 13 May 2026 15:35:08 +0200
From: Szabolcs Nagy <nsz@...t70.net>
To: Florian Schmaus <florian.schmaus@...asip.com>
Cc: musl@...ts.openwall.com, dalias@...c.org, tg@...bsd.de
Subject: Re: [PATCH v2] qsort: align 'tmp' buffer to preserve CHERI
capabilities
* Florian Schmaus <florian.schmaus@...asip.com> [2026-05-13 10:21:46 +0200]:
> The cycle() function in qsort.c uses a local stack buffer 'tmp'
> to temporarily hold elements being permuted.
>
> Under CHERI architectures, like CHERI RISC-V, pointers are represented
> as capabilities, which include an out-of-band hardware tag bit used to
> enforce memory safety. For this tag bit to be preserved when a
> capability is written to memory, the target address must be strictly
> aligned to the capability's size requirement (e.g., 16-byte aligned
> for 128-bit capabilities).
>
> Previously, 'tmp' was declared as an 'unsigned char' array, which only
> guarantees a 1-byte alignment. If qsort is called to sort an array of
> pointers, writing these capabilities into an unaligned 'tmp' buffer
> may cause the processor to strip their validity tags (depending on
> the actual alignment at run-time). When these untagged capabilities
> are copied back out and later dereferenced, the hardware will throw a
> capability fault, crashing the program.
>
> By changing the buffer type to a union with a pointer member we force
> the compiler to align the stack allocation to the architectural
> pointer/capability alignment boundary. This ensures that capabilities
> stored in the buffer retain their tags and remain valid.
> ---
> Changes in v2:
> - Use union to guarantee proper alignment
>
> src/stdlib/qsort.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c
> index 28607450b885..ffd523f7cd8c 100644
> --- a/src/stdlib/qsort.c
> +++ b/src/stdlib/qsort.c
> @@ -44,7 +44,12 @@ static inline int pntz(size_t p[2]) {
>
> static void cycle(size_t width, unsigned char* ar[], int n)
> {
> - unsigned char tmp[256];
> + /* Union forces pointer alignment to preserve CHERI capability tags */
> + union {
> + unsigned char c[256];
> + void *p;
> + } tmp_u;
> + unsigned char *tmp = tmp_u.c;
> size_t l;
> int i;
i guess this can be part of a cheri target port patchset.
cheri c is incompatible with standard c that allows
byte-by-byte copy of pointers. in cheri memcpy this can
be worked around if dst,src,size are aligned, but musl
does not have such a memcpy.
i think without cheri target support such changes need
stronger justification: either the behaviour improves
(e.g. memcpy may work better if tmp is aligned) or the
code quality improves (e.g. makes the intention clearer).
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.