diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2023-07-13 16:32:37 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2023-07-13 16:40:15 -0700 |
commit | de316ecee0c8fea0bf7fbea8a675a7dd46d0946b (patch) | |
tree | 600226b773ae6dbe20f9ba0f68fefa29e9f56525 | |
parent | 0f75c3d7e674a89c95717ea8e49e1aafb183d2ad (diff) |
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.
-rw-r--r-- | src/til_stream.c | 2 |
1 files changed, 2 insertions, 0 deletions
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; } |