From: Jérémie Galarneau Date: Fri, 9 Jul 2021 17:00:56 +0000 (-0400) Subject: Fix: sessiond: list-triggers: don't return internal triggers X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=f2bda80eb1fe2f73dda9a7590d9960cdccb0f733;p=lttng-tools.git Fix: sessiond: list-triggers: don't return internal triggers 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 Change-Id: I61b7949075172fcd428289e2eb670d03c19bdf71 --- diff --git a/include/lttng/trigger/trigger-internal.h b/include/lttng/trigger/trigger-internal.h index d917ffa01..80cf0cb56 100644 --- a/include/lttng/trigger/trigger-internal.h +++ b/include/lttng/trigger/trigger-internal.h @@ -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. diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 284f2921b..3349ff000 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -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; diff --git a/src/bin/lttng-sessiond/notification-thread-events.c b/src/bin/lttng-sessiond/notification-thread-events.c index c5ee4b11e..109378411 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.c +++ b/src/bin/lttng-sessiond/notification-thread-events.c @@ -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) && diff --git a/src/bin/lttng-sessiond/notification-thread-internal.h b/src/bin/lttng-sessiond/notification-thread-internal.h index e835bd6af..800e8fd83 100644 --- a/src/bin/lttng-sessiond/notification-thread-internal.h +++ b/src/bin/lttng-sessiond/notification-thread-internal.h @@ -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. diff --git a/src/bin/lttng-sessiond/rotate.c b/src/bin/lttng-sessiond/rotate.c index ec0aa6668..cdf95f353 100644 --- a/src/bin/lttng-sessiond/rotate.c +++ b/src/bin/lttng-sessiond/rotate.c @@ -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); diff --git a/src/common/trigger.c b/src/common/trigger.c index a599fa398..e708694b1 100644 --- a/src/common/trigger.c +++ b/src/common/trigger.c @@ -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: