From de316ecee0c8fea0bf7fbea8a675a7dd46d0946b Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Thu, 13 Jul 2023 16:32:37 -0700 Subject: til_stream: update tap ptr in til_stream_tap new pipe case The tap->ptr indirection must always be updated even when we're the driver on a fresh pipe created by us. This bug only triggers when the caller's tap was already on-stream, without being the driver, and the driving tap/context has since exited the stream, untapping itself which removed the associated pipes - even the ones it didn't own but was driving. In that scenario when pipe is created by the previously non-driving tap on its first update since the driver exited, its tap->ptr still points at the stale driver. This manifested as a UAF bug in that case. The fix is a simple matter of always updating tap->ptr to reflect the driving tap. This also fixes the real bug causing 468c78e3 to crash, such that the syncronous gc performed there shouldn't really be necessary to prevent crashing. It was the awkward overlapping existence of contexts at the same path which produced the triggering lifecycle pattern WRT driving taps at that path. --- src/til_stream.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/til_stream.c b/src/til_stream.c index aeab4b7..a16c3af 100644 --- a/src/til_stream.c +++ b/src/til_stream.c @@ -281,6 +281,8 @@ int til_stream_tap(til_stream_t *stream, const void *owner, const void *owner_fo pipe->next = stream->pipe_buckets[bucket]; stream->pipe_buckets[bucket] = pipe; + *(tap->ptr) = pipe->driving_tap->elems; + pthread_mutex_unlock(&stream->mutex); return 0; } -- cgit v1.2.3