[Mosquitto] Use-after-free during broker shutdown with active client
From the ML:
Use-after-free during broker shutdown with active client (mux_poll__add crash with ASan)
## Bug Summary
When shutting down Mosquitto after a client has connected and is still connected, the server crashes with an AddressSanitizer (ASan) `SEGV on unknown address`. The crash occurs inside the `mux_poll__add` function, attempting to update `pollfds[context->pollfd_index]`, whose memory appears already unmapped.
This suggests a **use-after-free** bug during shutdown/cleanup when client contexts are still active.
## Environment
- Mosquitto version: 2.0.21 (commit `89c52f9e`)
- Build: ASan enabled, no epoll (`WITH_EPOLL=no WITH_ASAN=yes`)
- OS: Ubuntu 20.04.6 LTS
- GCC/Clang: Clang 10.0.0
## Reproduction Steps
1. Compile and Build with ASan
```bash
git clone https://github.com/eclipse-mosquitto/mosquitto.git
cd mosquitto
git checkout 89c52f9e
make binary WITH_EPOLL:=no WITH_ASAN=yes
2. Run
Step 1: (Terminal 1) ./src/mosquitto
Step 2: (Terminal 2) cat /path/to/poc_0 | nc 127.0.0.1 1883
Step 3: (Terminal 3) kill -SIGTERM <mosquitto_pid>
3. Observe this ASan crash:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==376006==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x0000004ff20f bp 0x6170000007f8 sp 0x7ffe88af3b20 T0)
==376006==The signal is caused by a WRITE memory access.
==376006==Hint: address points to the zero page.
#0 0x4ff20f in mux_poll__add /home/ubuntu/experiments/mosquitto-latest/src/mux_poll.c:118:37
#1 0x4ff20f in mux_poll__add_out /home/ubuntu/experiments/mosquitto-latest/src/mux_poll.c:143:9
#2 0x50ad57 in packet__write /home/ubuntu/experiments/mosquitto-latest/src/../lib/packet_mosq.c:250:3
#3 0x53692c in send__real_publish /home/ubuntu/experiments/mosquitto-latest/src/../lib/send_publish.c:220:9
#4 0x53617c in send__publish /home/ubuntu/experiments/mosquitto-latest/src/../lib/send_publish.c:133:9
#5 0x4ed86c in db__message_write_inflight_out_single /home/ubuntu/experiments/mosquitto-latest/src/database.c:1117:9
#6 0x4e932f in db__message_write_inflight_out_latest /home/ubuntu/experiments/mosquitto-latest/src/database.c:1205:10
#7 0x4e932f in db__message_insert /home/ubuntu/experiments/mosquitto-latest/src/database.c:622:8
#8 0x546cb8 in subs__send /home/ubuntu/experiments/mosquitto-latest/src/subs.c:100:6
#9 0x546862 in subs__process /home/ubuntu/experiments/mosquitto-latest/src/subs.c:143:9
#10 0x54461d in sub__search /home/ubuntu/experiments/mosquitto-latest/src/subs.c:535:8
#11 0x5445e6 in sub__search /home/ubuntu/experiments/mosquitto-latest/src/subs.c:491:9
#12 0x54366e in sub__messages_queue /home/ubuntu/experiments/mosquitto-latest/src/subs.c:679:15
#13 0x4eab17 in db__messages_easy_queue /home/ubuntu/experiments/mosquitto-latest/src/database.c:751:9
#14 0x4decc3 in context__send_will /home/ubuntu/experiments/mosquitto-latest/src/context.c:202:4
#15 0x4c7dd4 in main /home/ubuntu/experiments/mosquitto-latest/src/mosquitto.c:595:3
#16 0x7ff957675082 in __libc_start_main /build/glibc-FcRMwW/glibc-2.31/csu/../csu/libc-start.c:308:16
#17 0x41ed4d in _start (/home/ubuntu/experiments/mosquitto-latest/src/mosquitto+0x41ed4d)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ubuntu/experiments/mosquitto-latest/src/mux_poll.c:118:37 in mux_poll__add
==376006==ABORTING
## Root Cause Hypothesis
The crash appears to be caused by a use-after-free bug related to the pollfds array.
In the function main() (located in mosquitto.c), line 587, mosquitto_main_loop() is called. Upon returning, this function cleans up the server resources, including deallocating the pollfds structure.
However, after this cleanup, on line 595, context__send_will() is called in a loop:
HASH_ITER(hh_id, db.contexts_by_id, ctxt, ctxt_tmp){
context__send_will(ctxt);
}
Inside the subsequent call chain from context__send_will(), mux_poll__add() may be triggered (via db__messages_easy_queue() and related functions), which attempts to access pollfds[context->pollfd_index].
At this point, since pollfds has already been freed by mosquitto_main_loop(), the access in mux_poll__add() leads to undefined behavior — in this case, a crash detected by AddressSanitizer
I believe this vulnerability could have a significant impact on users and should be tracked using a CVE ID.
Please let me know if you need any additional information in order to assign a CVE ID or if further testing is required.
Thank you for your attention to this matter. I look forward to hearing from you.