From: Mathieu Desnoyers Date: Fri, 10 Jul 2020 15:15:40 +0000 (-0400) Subject: Fix: metadata stream leak, missing list removal and locking X-Git-Tag: v2.12.2~2 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=e0d82ce5441766ce266878f0638981e51002523e;p=lttng-modules.git Fix: metadata stream leak, missing list removal and locking The metadata stream is part of a list of metadata streams in the metadata cache. Its addition to the list should be protected by the metadata cache lock. It needs to be paired with protection of list iteration with the same lock. Removal from the list is entirely missing, and should be added to lttng_metadata_ring_buffer_release (with proper locking). This missing list removal was probably not causing issues because the metadata stream structure was leaked: a kfree() is missing from lttng_metadata_ring_buffer_release as well. Signed-off-by: Mathieu Desnoyers --- diff --git a/lttng-abi.c b/lttng-abi.c index 0996f2f1..64ea99da 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -1090,8 +1090,12 @@ int lttng_metadata_ring_buffer_release(struct inode *inode, struct file *file) struct lttng_metadata_stream *stream = file->private_data; struct lib_ring_buffer *buf = stream->priv; + mutex_lock(&stream->metadata_cache->lock); + list_del(&stream->list); + mutex_unlock(&stream->metadata_cache->lock); kref_put(&stream->metadata_cache->refcount, metadata_cache_destroy); module_put(stream->transport->owner); + kfree(stream); return lib_ring_buffer_release(inode, file, buf); } @@ -1243,8 +1247,10 @@ int lttng_abi_open_metadata_stream(struct file *channel_file) if (ret < 0) goto fd_error; + mutex_lock(&session->metadata_cache->lock); list_add(&metadata_stream->list, &session->metadata_cache->metadata_stream); + mutex_unlock(&session->metadata_cache->lock); return ret; fd_error: diff --git a/lttng-events.c b/lttng-events.c index b7c183e9..59b37b93 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -1696,9 +1696,9 @@ void lttng_metadata_end(struct lttng_session *session) if (atomic_dec_return(&session->metadata_cache->producing) == 0) { struct lttng_metadata_stream *stream; - mutex_unlock(&session->metadata_cache->lock); list_for_each_entry(stream, &session->metadata_cache->metadata_stream, list) wake_up_interruptible(&stream->read_wait); + mutex_unlock(&session->metadata_cache->lock); } }