[Bug] mq_open() / mq_unlink() build /dev/mqueue/<name> with rt_sprintf() into a fixed stack buffer, allowing stack overflow
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 62/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Tranquilla
- Stack tecnologico
- c
- Ambito
- operating-systems, security
Direzione di ricerca
Inizia in components/libc/posix/ipc/mqueue.c, nelle posizioni indicate di mq_open() e mq_unlink(), quindi esamina i punti di raggiungibilità in lwp_syscall.c alle righe 9057 e 9122. Verifica la build di POSIX mqueue e i casi limite descritti nei passaggi per la riproduzione. Il lavoro è completato quando entrambi i percorsi rifiutano i nomi che non possono essere contenuti e costruiscono in sicurezza il percorso della coda senza Stack Overflow.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
RT-Thread Version
master, verified on origin/master at commit 25295501c0cc7181d6a541a867fdf7214879ddf8, first appear in v5.0.2 at commit d6adf6708f6e0666d040e553a81b24edcc92c374
Hardware Type/Architectures
Any architecture using components/libc/posix/ipc/mqueue.c
Develop Toolchain
GCC
Describe the bug
Summary
A stack-based buffer overflow exists in RT-Thread's POSIX message queue implementation.
mq_open() and mq_unlink() build the path string "/dev/mqueue/<name>" into a fixed-size stack buffer using unbounded rt_sprintf().
The buffer is declared as:
char mq_name[RT_NAME_MAX + 12];
However, the required size for the resulting string is:
strlen("/dev/mqueue/") + strlen(name) + 112 + strlen(name) + 1
So the true safe condition is strlen(name) <= RT_NAME_MAX - 1. Current code does not enforce that condition.
Affected Locations
components/libc/posix/ipc/mqueue.c:121components/libc/posix/ipc/mqueue.c:164components/libc/posix/ipc/mqueue.c:465
Vulnerability Details
1. mq_open() contains an off-by-one stack overflow
mq_open() checks:
if (len > RT_NAME_MAX) {
rt_set_errno(ENAMETOOLONG);
return (mqd_t)(-1);
}
But it later uses:
rt_sprintf(mq_name, "%s%s", mq_path, name);
with:
char mq_name[RT_NAME_MAX + 12];
Since the prefix "/dev/mqueue/" is 12 bytes and sprintf also writes the terminating NUL byte, len == RT_NAME_MAX already overflows the stack buffer by 1 byte. The current guard is insufficient.
2. mq_unlink() contains an unbounded stack overflow
mq_unlink() uses the same fixed-size stack buffer and the same rt_sprintf() path construction logic, but does not perform an equivalent length check first.
A long name can therefore overflow the stack buffer by more than 1 byte — potentially by an arbitrarily large amount depending on the input length.
Reachability
This is not a remote issue. However, it is practically reachable by local callers.
In systems using LWP/MMU, the syscall layer copies the user-provided message queue name into kernel memory and then invokes mq_open() / mq_unlink() without imposing a stricter length limit that would prevent this bug.
Relevant reachability points:
lwp_syscall.c:9057lwp_syscall.c:9122
An untrusted local userspace process can supply an oversized queue name and trigger these kernel-side stack overflows.
Impact
- Local kernel stack overflow
- Local denial of service
- Possible local privilege escalation, depending on platform, compiler, calling convention, stack protector configuration, and surrounding memory layout
If the product does not run untrusted local processes, this may be treated as a severe robustness bug. If the product uses LWP userspace isolation and executes untrusted local code, this is a real local security vulnerability.
Steps to Reproduce
mq_open() off-by-one case
-
Build RT-Thread with POSIX mqueue support enabled.
-
Call
mq_open()with a queue name whose length is exactlyRT_NAME_MAX. -
Ensure the path construction reaches:
rt_sprintf(mq_name, "%s%s", mq_path, name); -
Observe that the fixed stack buffer is overrun by 1 byte.
mq_unlink() unbounded case
- Build RT-Thread with POSIX mqueue support enabled.
- Call
mq_unlink()with a very long queue name. - Observe that the same fixed stack buffer is used with
rt_sprintf()and no sufficient length guard. - The stack buffer can be overflowed by a larger attacker-controlled amount.
Expected Behavior
RT-Thread should safely construct the queue path without overflowing the stack buffer.
At minimum:
- Use bounded formatting, e.g.
rt_snprintf(mq_name, sizeof(mq_name), "%s%s", mq_path, name) - Reject names that cannot fit including the prefix and terminating NUL
- Treat
len >= RT_NAME_MAXas too long in the current buffer sizing scheme - Apply the same validation to both
mq_open()andmq_unlink()
Actual Behavior
mq_open()allowslen == RT_NAME_MAX, which causes a deterministic 1-byte stack overflowmq_unlink()uses the same fixed stack buffer and unboundedrt_sprintf()without adequate length validation, allowing larger stack overflows
Suggested Fix
1. Replace unbounded rt_sprintf() with bounded variant
// Before
rt_sprintf(mq_name, "%s%s", mq_path, name);
// After
rt_snprintf(mq_name, sizeof(mq_name), "%s%s", mq_path, name);
2. Fix the off-by-one in mq_open() length check
// Before
if (len > RT_NAME_MAX)
// After
if (len >= RT_NAME_MAX)
3. Add equivalent length validation to mq_unlink()
Apply the same length check before formatting the path, consistent with the corrected mq_open() guard.
Kindly let me know if you intend to request a CVE ID upon confirmation of the vulnerability.
Other additional context
No response
- Lingua principale
- C
- Stelle
- 12.3k
- Fork
- 5.5k
- Merge medio
- 4g 12h
- PR unite (30g)
- 32
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di RT-Thread/rt-thread
-
[Bug] [netdev] ping crashes the shell with a division by zero when the target is unreachable (received == 0)Forse già presa Una pull request collegata a questa issue è aperta o già unita. Apertabug Component component: net
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
RT-Thread/rt-thread#11852 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
[bsp][stm32][bluepill] README「快速上手」缺少重新生成 MDK 工程这一步,按文档操作无法编译通过Forse già presa @moment-NEW l’ha presa 3 giorni fa. Apertain progress
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
RT-Thread/rt-thread#11818 · 4 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
BSP BSP: Loongson bug RT-Smart
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
RT-Thread/rt-thread#11717 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Arch: RISC-V BSP BSP: HPMicro bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
RT-Thread/rt-thread#11687 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
RT-Thread/rt-thread#11472 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di RT-Thread/rt-thread
Issue simili
-
[P2] Workspace updates silently ignore forbidden assignments while staging the rowForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 70/100
I maintainer di solito rispondono entro 4 giorni
-
sdl3-image update to 3.4.8Apertacategory:port-update
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
microsoft/vcpkg#54338 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
area:http-gateway good first issue priority:low type:docs
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
crazy-goat/php-fpm-ng#828 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 63/100
SunDevilRocketry/Flight-Computer-Firmware#347 ·
I maintainer di solito rispondono entro 3 giorni