Open anarthal opened 1 year ago
This could be fixed after my last merge on develop where I remove the use of associated allocator.
Even if you use the standard allocator, I'd say you should free any temporary memory acquired by the operation before calling complete, unless there is a strong reason not to do so, so that allocations don't stack up. But probably Klemens can give you a better understanding of the subject.
Memory for
req_info_type
inexec_op
is being allocated using the handler's associated allocator, but is not being freed before callingcomplete
. This is a violation of one of Asio's composed ops principles.This has been caught by ubsan when using Boost.Redis together with Boost.Async (I'm exercising the library by rewriting BoostServerTech). Boost.Async uses an internal, per-operation allocator. That is, when you call
conn.async_exec(whatever, use_op)
, a stack-based memory pool of 2kb is created. All allocations for thisasync_exec
will use these 2kb of memory first. Once thisasync_exec
operation is done, the pool is destroyed. However, the callself.complete
withinasync_exec
resumes and keeps executing the coroutine that calledasync_exec
. At this point,async_exec
has areq_info_type
object pointing to memory that has been freed (or re-used). When theshared_ptr<req_info_type>
destructor runs, it will be accessing freed memory.It's likely that this can be used to build exploits leading to arbitrary code execution.