|
|
Message-ID: <20260513082146.39019-1-florian.schmaus@codasip.com>
Date: Wed, 13 May 2026 10:21:46 +0200
From: Florian Schmaus <florian.schmaus@...asip.com>
To: musl@...ts.openwall.com
Cc: dalias@...c.org,
tg@...bsd.de,
Florian Schmaus <florian.schmaus@...asip.com>
Subject: [PATCH v2] qsort: align 'tmp' buffer to preserve CHERI capabilities
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;
--
2.53.0
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.