Fix: sessiond: list-triggers: don't return internal triggers
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 9 Jul 2021 17:00:56 +0000 (13:00 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 12 Jul 2021 21:38:52 +0000 (17:38 -0400)
The session daemon uses triggers internally. For instance, the trigger
and notification subsystem is used to implement the automatic rotation
of sessions based on a size threshold.

Currently, a user of the C API will see those internal triggers if it is
running as the same user as the session daemon. This can be unexpected
by user code that assumes it will be alone in creating triggers.
Moreover, it is possible for external users to unregister those triggers
which would cause bugs.

As the triggers gain more capabilities, it is likely that the session
daemon will keep using them to implement features internally. Thus,
an internal "is_hidden" property is introduced in lttng_trigger.

A "hidden" trigger is a trigger that is not returned by the listings.
It is used to hide triggers that are used internally by the session
daemon so that they can't be listed nor unregistered by external
clients.

This is a property that can only be set internally by the session
daemon. As such, it is not serialized nor set by a
"create_from_buffer" constructor.

The hidden property is preserved by copies.

Note that notifications originating from an "hidden" trigger will not
be sent to clients that are not within the session daemon's process.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I61b7949075172fcd428289e2eb670d03c19bdf71

include/lttng/trigger/trigger-internal.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/notification-thread-events.c
src/bin/lttng-sessiond/notification-thread-internal.h
src/bin/lttng-sessiond/rotate.c
src/common/trigger.c

index d917ffa011d13a4db5486cde3f27c46b99177552..80cf0cb56023260ef3236110af266edf3a319b8a 100644 (file)
@@ -53,6 +53,23 @@ struct lttng_trigger {
         */
        bool registered;
 
+       /*
+        * A "hidden" trigger is a trigger that is not externally listed.
+        * It is used to hide triggers that are used internally by the session
+        * daemon so that they can't be listed nor unregistered by external
+        * clients.
+        *
+        * This is a property that can only be set internally by the session
+        * daemon. As such, it is not serialized nor set by a
+        * "create_from_buffer" constructor.
+        *
+        * The hidden property is preserved by copies.
+        *
+        * Note that notifications originating from an "hidden" trigger will not
+        * be sent to clients that are not within the session daemon's process.
+        */
+       bool is_hidden;
+
        /*
         * The lock is used to protect against concurrent trigger execution and
         * trigger removal.
@@ -118,6 +135,12 @@ LTTNG_HIDDEN
 bool lttng_trigger_is_equal(
                const struct lttng_trigger *a, const struct lttng_trigger *b);
 
+LTTNG_HIDDEN
+bool lttng_trigger_is_hidden(const struct lttng_trigger *trigger);
+
+LTTNG_HIDDEN
+void lttng_trigger_set_hidden(struct lttng_trigger *trigger);
+
 LTTNG_HIDDEN
 void lttng_trigger_get(struct lttng_trigger *trigger);
 
@@ -165,6 +188,12 @@ LTTNG_HIDDEN
 int lttng_triggers_add(
                struct lttng_triggers *triggers, struct lttng_trigger *trigger);
 
+/*
+ * Remove all triggers marked as hidden from the provided trigger set.
+ */
+LTTNG_HIDDEN
+int lttng_triggers_remove_hidden_triggers(struct lttng_triggers *triggers);
+
 /*
  * Serialize a trigger set to an lttng_payload object.
  * Return LTTNG_OK on success, negative lttng error code on error.
index 284f2921b2d551eb588d26ed2a03016dae9c7cfd..3349ff000f415d60073760085f8fce0de156c105 100644 (file)
@@ -4635,6 +4635,7 @@ enum lttng_error_code cmd_list_triggers(struct command_ctx *cmd_ctx,
                struct notification_thread_handle *notification_thread,
                struct lttng_triggers **return_triggers)
 {
+       int ret;
        enum lttng_error_code ret_code;
        struct lttng_triggers *triggers = NULL;
 
@@ -4645,6 +4646,12 @@ enum lttng_error_code cmd_list_triggers(struct command_ctx *cmd_ctx,
                goto end;
        }
 
+       ret = lttng_triggers_remove_hidden_triggers(triggers);
+       if (ret) {
+               ret_code = LTTNG_ERR_UNK;
+               goto end;
+       }
+
        *return_triggers = triggers;
        triggers = NULL;
        ret_code = LTTNG_OK;
index c5ee4b11ed02052a77f014103b675e93336d6f71..1093784113cd4e2b35cc5093ab3dd7d5b5bc6b69 100644 (file)
@@ -3814,9 +3814,11 @@ int client_handle_message_handshake(struct notification_client *client,
                        &client->communication.inbound.creds);
        client->gid = LTTNG_SOCK_GET_GID_CRED(
                        &client->communication.inbound.creds);
-       DBG("Received handshake from client (uid = %u, gid = %u) with version %i.%i",
+       client->is_sessiond = LTTNG_SOCK_GET_PID_CRED(&client->communication.inbound.creds) == getpid();
+       DBG("Received handshake from client: uid = %u, gid = %u, protocol version = %i.%i, client is sessiond = %s",
                        client->uid, client->gid, (int) client->major,
-                       (int) client->minor);
+                       (int) client->minor,
+                       client->is_sessiond ? "true" : "false");
 
        if (handshake_client->major !=
                        LTTNG_NOTIFICATION_CHANNEL_VERSION_MAJOR) {
@@ -4414,6 +4416,14 @@ int notification_client_list_send_evaluation(
                        goto skip_client;
                }
 
+               if (lttng_trigger_is_hidden(trigger) && !client->is_sessiond) {
+                       /*
+                        * Notifications resulting from an hidden trigger are
+                        * only sent to the session daemon.
+                        */
+                       continue;
+               }
+
                if (source_object_creds) {
                        if (client->uid != lttng_credentials_get_uid(source_object_creds) &&
                                        client->gid != lttng_credentials_get_gid(source_object_creds) &&
index e835bd6afe3cad4ab2532059db867aeb16e59e6a..800e8fd837a2817a666cc726596fc63fdc2a2a76 100644 (file)
@@ -142,6 +142,7 @@ struct notification_client {
        uint8_t major, minor;
        uid_t uid;
        gid_t gid;
+       bool is_sessiond;
        /*
         * Indicates if the credentials and versions of the client have been
         * checked.
index ec0aa666837d6b6346e14047d11800584f5bc25a..cdf95f353dbbfa2cb0ba276cdba6292d26dc92ae 100644 (file)
@@ -92,6 +92,8 @@ int subscribe_session_consumed_size_rotation(struct ltt_session *session, uint64
                goto end;
        }
 
+       /* Ensure this trigger is not visible to external users. */
+       lttng_trigger_set_hidden(session->rotate_trigger);
        lttng_trigger_set_credentials(
                        session->rotate_trigger, &session_creds);
 
index a599fa3982b98853951d2f8f296007aa67fe4970..e708694b1c0969a7feb649691af0c9b411f05cac 100644 (file)
@@ -370,9 +370,26 @@ bool lttng_trigger_is_equal(
                return false;
        }
 
+       if (a->is_hidden != b->is_hidden) {
+               return false;
+       }
+
        return true;
 }
 
+LTTNG_HIDDEN
+bool lttng_trigger_is_hidden(const struct lttng_trigger *trigger)
+{
+       return trigger->is_hidden;
+}
+
+LTTNG_HIDDEN
+void lttng_trigger_set_hidden(struct lttng_trigger *trigger)
+{
+       assert(!trigger->is_hidden);
+       trigger->is_hidden = true;
+}
+
 LTTNG_HIDDEN
 enum lttng_trigger_status lttng_trigger_set_name(struct lttng_trigger *trigger,
                const char* name)
@@ -550,6 +567,40 @@ int lttng_triggers_add(
        return ret;
 }
 
+LTTNG_HIDDEN
+int lttng_triggers_remove_hidden_triggers(struct lttng_triggers *triggers)
+{
+       int ret;
+       unsigned int trigger_count, i = 0;
+       enum lttng_trigger_status trigger_status;
+
+       assert(triggers);
+
+       trigger_status = lttng_triggers_get_count(triggers, &trigger_count);
+       assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+
+       while (i < trigger_count) {
+               const struct lttng_trigger *trigger =
+                               lttng_triggers_get_at_index(triggers, i);
+
+               if (lttng_trigger_is_hidden(trigger)) {
+                       ret = lttng_dynamic_pointer_array_remove_pointer(
+                                       &triggers->array, i);
+                       if (ret) {
+                               goto end;
+                       }
+
+                       trigger_count--;
+               } else {
+                       i++;
+               }
+       }
+
+       ret = 0;
+end:
+       return ret;
+}
+
 const struct lttng_trigger *lttng_triggers_get_at_index(
                const struct lttng_triggers *triggers, unsigned int index)
 {
@@ -942,6 +993,7 @@ struct lttng_trigger *lttng_trigger_copy(const struct lttng_trigger *trigger)
 
        copy->tracer_token = trigger->tracer_token;
        copy->registered = trigger->registered;
+       copy->is_hidden = trigger->is_hidden;
        goto end;
 
 error_cleanup_trigger:
This page took 0.031792 seconds and 4 git commands to generate.