UAF via shared lock lifetime mismatch in `bufferevent_finalize_cb_`
Author: BrubbishCreated Mar 17, 2026Updated May 25, 2026
Summary
When evbuffer_add_buffer_reference() makes an evbuffer’s refcount > 1, calling bufferevent_free() can free a shared lock while the evbuffer remains alive. Any subsequent lock operation on that evbuffer can dereference a freed lock pointer, causing a use‑after‑free.
Affected Version
- libevent built from source (commit id: a994a52d5373d6284b27576efa617aff2baa7bd3)
- Components:
bufferevent.c,buffer.c
Reproduction Environment
- Debian trixie container
- AddressSanitizer (ASAN)
Vulnerability Details
Location
bufferevent_finalize_cb_inbufferevent.cevbuffer_decref_and_unlock_inbuffer.cevbuffer_add_buffer_referenceinbuffer.c
Root Cause (code pattern)
// bufferevent_finalize_cb_()
/* evbuffer will free the callbacks */
evbuffer_free(bufev->input);
evbuffer_free(bufev->output);
...
if (bufev_private->own_lock)
EVTHREAD_FREE_LOCK(bufev_private->lock, EVTHREAD_LOCKTYPE_RECURSIVE);If evbuffer_add_buffer_reference() has incremented the evbuffer refcount, evbuffer_free() only decrements the refcount and does not destroy the buffer. However, bufferevent_finalize_cb_() still frees the shared lock. The surviving evbuffer then uses a dangling lock pointer.
PoC / Steps to Reproduce
1) PoC Source
2) Build & Run (container)
docker run --rm -v /home/bruce/libevent:/src debian-trixie-tsinghua:latest bash -lc "
set -e
apt-get update >/dev/null
apt-get install -y build-essential cmake autoconf automake libtool pkg-config >/dev/null
rm -rf /src/build && mkdir -p /src/build && cd /src/build
cmake -DEVENT__DISABLE_TESTS=ON -DEVENT__DISABLE_BENCHMARK=ON .. >/dev/null
cmake --build . -j2 >/dev/null
cd /src/poc
gcc -g -fsanitize=address -I/src -I/src/include -I/src/build/include -L/src/build/lib \
poc_uaf_lock.c -o poc_uaf_lock -levent -levent_core -levent_extra -levent_pthreads -pthread
ASAN_OPTIONS=detect_odr_violation=0 LD_LIBRARY_PATH=/src/build/lib ./poc_uaf_lock
"3) Expected ASAN Result
==1==ERROR: AddressSanitizer: heap-use-after-free on address 0x50d000000078 at pc 0x5614b35499e4 bp 0x7ffc9e7bf6c0 sp 0x7ffc9e7bf6b8
READ of size 8 at 0x50d000000078 thread T0
#0 0x5614b35499e3 in main /src/poc/poc_uaf_lock.c:89
#1 0x7f7b0310dca7 (/lib/x86_64-linux-gnu/libc.so.6+0x29ca7) (BuildId: 58749c528985eab03e6700ebc1469fa50aa41219)
#2 0x7f7b0310dd64 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29d64) (BuildId: 58749c528985eab03e6700ebc1469fa50aa41219)
#3 0x5614b3549270 in _start (/src/poc/poc_uaf_lock+0x2270) (BuildId: 6395d19b949aa674aaebe690eed280c5504f30cc)
0x50d000000078 is located 56 bytes inside of 144-byte region [0x50d000000040,0x50d0000000d0)
freed by thread T0 here:
#0 0x7f7b034c08f8 in free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:52
#1 0x7f7b0337d347 in bufferevent_finalize_cb_ (/src/build/lib/libevent-2.2.so.1+0x1d347) (BuildId: 86dd64a7209032eeb6e3047fe7ac180d2569754f)
previously allocated by thread T0 here:
#0 0x7f7b034c1610 in calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77
#1 0x7f7b03371d72 in evbuffer_new (/src/build/lib/libevent-2.2.so.1+0x11d72) (BuildId: 86dd64a7209032eeb6e3047fe7ac180d2569754f)
SUMMARY: AddressSanitizer: heap-use-after-free /src/poc/poc_uaf_lock.c:89 in main
Impact
Use‑after‑free of a mutex/lock associated with an evbuffer can lead to crashes and potentially security issues in threaded environments.
Source: libevent/libevent