All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
To: lttng-dev@lists.lttng.org
Cc: jgalar@efficios.com
Subject: [lttng-tools RFC] Fix: registry can be null on lookup
Date: Mon,  6 Feb 2017 15:28:52 -0500	[thread overview]
Message-ID: <1486412932-12806-1-git-send-email-jonathan.rajotte-julien__39213.1268083633$1486412968$gmane$org@efficios.com> (raw)

A session teardown can be initiated by a dying application. Hence, a
session object can exist without a valid registry. As a result,
get_session_registry can return null. To prevent this, the UST
application session lock should be held, when possible, when looking up
the registry to ensure synchronization. Otherwise the presence of a
registry is not guaranteed. In such case, handling a null return value
from look-up registry function is necessary.

Core dumps, triggered by the "assert(registry)" statement found in
reply_ust_register_channel, were observed when killing instrumented
applications. In this occurrence, obtaining the UST application lock
result in a deadlock since the lock is already held during
ust_app_global_create. Handling the null value is simpler and
corresponds with the handling of previous look-up done during the
function.

Handling of null value is also applied to:
	add_event_ust_registry
	add_enum_ust_registry
	ust_app_snapshot_record

Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
---
 src/bin/lttng-sessiond/ust-app.c | 53 ++++++++++++++++++++++++++++++++++------
 1 file changed, 45 insertions(+), 8 deletions(-)

diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c
index 5a41c38..4395a59 100644
--- a/src/bin/lttng-sessiond/ust-app.c
+++ b/src/bin/lttng-sessiond/ust-app.c
@@ -810,6 +810,7 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess,
 	ua_sess->deleted = true;
 
 	registry = get_session_registry(ua_sess);
+	/* Registry can be null on error path during initialization */
 	if (registry) {
 		/* Push metadata for application before freeing the application. */
 		(void) push_metadata(registry, ua_sess->consumer);
@@ -837,6 +838,10 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess,
 	if (ua_sess->buffer_type == LTTNG_BUFFER_PER_PID) {
 		struct buffer_reg_pid *reg_pid = buffer_reg_pid_find(ua_sess->id);
 		if (reg_pid) {
+			/*
+			 * Registry can be null on error path during
+			 * initialization
+			 */
 			buffer_reg_pid_remove(reg_pid);
 			buffer_reg_pid_destroy(reg_pid);
 		}
@@ -2464,6 +2469,8 @@ error:
 /*
  * Ask the consumer to create a channel and get it if successful.
  *
+ * Called with UST app session lock held.
+ *
  * Return 0 on success or else a negative value.
  */
 static int do_consumer_create_channel(struct ltt_ust_session *usess,
@@ -2917,6 +2924,8 @@ error:
 /*
  * Create and send to the application the created buffers with per PID buffers.
  *
+ * Called with UST app session lock held.
+ *
  * Return 0 on success else a negative value.
  */
 static int create_channel_per_pid(struct ust_app *app,
@@ -2936,6 +2945,7 @@ static int create_channel_per_pid(struct ust_app *app,
 	rcu_read_lock();
 
 	registry = get_session_registry(ua_sess);
+	/* The UST app session lock is held, registry shall not be null */
 	assert(registry);
 
 	/* Create and add a new channel registry to session. */
@@ -2973,6 +2983,8 @@ error:
  * need and send it to the application. This MUST be called with a RCU read
  * side lock acquired.
  *
+ * Called with UST app session lock held.
+ *
  * Return 0 on success or else a negative value. Returns -ENOTCONN if
  * the application exited concurrently.
  */
@@ -3160,6 +3172,7 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess,
 	assert(consumer);
 
 	registry = get_session_registry(ua_sess);
+	/* The UST app session is held registry shall not be null */
 	assert(registry);
 
 	pthread_mutex_lock(&registry->lock);
@@ -4296,6 +4309,9 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
 
 /*
  * Start tracing for a specific UST session and app.
+ *
+ * Called with UST app session lock held.
+ *
  */
 static
 int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app)
@@ -4479,6 +4495,8 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app)
 	health_code_update();
 
 	registry = get_session_registry(ua_sess);
+
+	/* The UST app session is held registry shall not be null */
 	assert(registry);
 
 	/* Push metadata for application before freeing the application. */
@@ -5320,7 +5338,7 @@ static int reply_ust_register_channel(int sock, int sobjd, int cobjd,
 	/* Lookup application. If not found, there is a code flow error. */
 	app = find_app_by_notify_sock(sock);
 	if (!app) {
-		DBG("Application socket %d is being teardown. Abort event notify",
+		DBG("Application socket %d is being torn down. Abort event notify",
 				sock);
 		ret = 0;
 		free(fields);
@@ -5330,7 +5348,7 @@ static int reply_ust_register_channel(int sock, int sobjd, int cobjd,
 	/* Lookup channel by UST object descriptor. */
 	ua_chan = find_channel_by_objd(app, cobjd);
 	if (!ua_chan) {
-		DBG("Application channel is being teardown. Abort event notify");
+		DBG("Application channel is being torn down. Abort event notify");
 		ret = 0;
 		free(fields);
 		goto error_rcu_unlock;
@@ -5341,7 +5359,12 @@ static int reply_ust_register_channel(int sock, int sobjd, int cobjd,
 
 	/* Get right session registry depending on the session buffer type. */
 	registry = get_session_registry(ua_sess);
-	assert(registry);
+	if (!registry) {
+		DBG("Application session is being torn down. Abort event notify");
+		ret = 0;
+		free(fields);
+		goto error_rcu_unlock;
+	};
 
 	/* Depending on the buffer type, a different channel key is used. */
 	if (ua_sess->buffer_type == LTTNG_BUFFER_PER_UID) {
@@ -5439,7 +5462,7 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name,
 	/* Lookup application. If not found, there is a code flow error. */
 	app = find_app_by_notify_sock(sock);
 	if (!app) {
-		DBG("Application socket %d is being teardown. Abort event notify",
+		DBG("Application socket %d is being torn down. Abort event notify",
 				sock);
 		ret = 0;
 		free(sig);
@@ -5451,7 +5474,7 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name,
 	/* Lookup channel by UST object descriptor. */
 	ua_chan = find_channel_by_objd(app, cobjd);
 	if (!ua_chan) {
-		DBG("Application channel is being teardown. Abort event notify");
+		DBG("Application channel is being torn down. Abort event notify");
 		ret = 0;
 		free(sig);
 		free(fields);
@@ -5463,7 +5486,14 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name,
 	ua_sess = ua_chan->session;
 
 	registry = get_session_registry(ua_sess);
-	assert(registry);
+	if (!registry) {
+		DBG("Application session is being torn down. Abort event notify");
+		ret = 0;
+		free(sig);
+		free(fields);
+		free(model_emf_uri);
+		goto error_rcu_unlock;
+	}
 
 	if (ua_sess->buffer_type == LTTNG_BUFFER_PER_UID) {
 		chan_reg_key = ua_chan->tracing_channel_id;
@@ -5551,7 +5581,11 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name,
 	}
 
 	registry = get_session_registry(ua_sess);
-	assert(registry);
+	if (!registry) {
+		DBG("Application session is being torn down. Aborting enum registration.");
+		free(entries);
+		goto error_rcu_unlock;
+	}
 
 	pthread_mutex_lock(&registry->lock);
 
@@ -5917,7 +5951,10 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess,
 			}
 
 			registry = get_session_registry(ua_sess);
-			assert(registry);
+			if (!registry) {
+				DBG("Application session is being torn down. Abort snapshot record.");
+				goto error;
+			}
 			ret = consumer_snapshot_channel(socket, registry->metadata_key, output,
 					1, ua_sess->euid, ua_sess->egid, pathname, wait, 0);
 			if (ret < 0) {
-- 
2.7.4

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

             reply	other threads:[~2017-02-06 20:32 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-06 20:28 Jonathan Rajotte [this message]
     [not found] <1486412932-12806-1-git-send-email-jonathan.rajotte-julien@efficios.com>
2017-06-01 19:42 ` [lttng-tools RFC] Fix: registry can be null on lookup Jérémie Galarneau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='1486412932-12806-1-git-send-email-jonathan.rajotte-julien__39213.1268083633$1486412968$gmane$org@efficios.com' \
    --to=jonathan.rajotte-julien@efficios.com \
    --cc=jgalar@efficios.com \
    --cc=lttng-dev@lists.lttng.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.