X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=2f5a4e98c74978d8ac8d7480cb539bc595e2afd7;hp=dc442035a3fe21e6b4c487a1007c9f05d1b38c56;hb=fbc9f37df245d544a7705ba576297df791220b44;hpb=d7b377ed1acd4043bde353d99122e0e56fa4e975 diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index dc442035a..2f5a4e98c 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -3107,10 +3107,22 @@ enum lttng_error_code cmd_create_session(struct command_ctx *cmd_ctx, int sock, &payload, 0, cmd_ctx->lsm.u.create_session.home_dir_size); + if (cmd_ctx->lsm.u.create_session.home_dir_size > 0 && + !lttng_buffer_view_is_valid(&home_dir_view)) { + ERR("Invalid payload in \"create session\" command: buffer too short to contain home directory"); + ret_code = LTTNG_ERR_INVALID_PROTOCOL; + goto error; + } + session_descriptor_view = lttng_buffer_view_from_dynamic_buffer( &payload, cmd_ctx->lsm.u.create_session.home_dir_size, cmd_ctx->lsm.u.create_session.session_descriptor_size); + if (!lttng_buffer_view_is_valid(&session_descriptor_view)) { + ERR("Invalid payload in \"create session\" command: buffer too short to contain session descriptor"); + ret_code = LTTNG_ERR_INVALID_PROTOCOL; + goto error; + } ret = lttng_session_descriptor_create_from_buffer( &session_descriptor_view, &session_descriptor); @@ -4257,7 +4269,8 @@ end: } int cmd_register_trigger(struct command_ctx *cmd_ctx, int sock, - struct notification_thread_handle *notification_thread) + struct notification_thread_handle *notification_thread, + struct lttng_trigger **return_trigger) { int ret; size_t trigger_len; @@ -4265,8 +4278,8 @@ int cmd_register_trigger(struct command_ctx *cmd_ctx, int sock, struct lttng_trigger *trigger = NULL; struct lttng_payload trigger_payload; struct lttng_credentials cmd_creds = { - .uid = cmd_ctx->creds.uid, - .gid = cmd_ctx->creds.gid, + .uid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.uid), + .gid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.gid), }; lttng_payload_init(&trigger_payload); @@ -4314,12 +4327,41 @@ int cmd_register_trigger(struct command_ctx *cmd_ctx, int sock, } } - /* Set the trigger credential */ - lttng_trigger_set_credentials(trigger, &cmd_creds); + /* + * Validate the trigger credentials against the command credentials. + * Only the root user can register a trigger with non-matching + * credentials. + */ + if (!lttng_credentials_is_equal_uid( + lttng_trigger_get_credentials(trigger), + &cmd_creds)) { + if (lttng_credentials_get_uid(&cmd_creds) != 0) { + ERR("Trigger credentials do not match the command credentials"); + ret = LTTNG_ERR_INVALID_TRIGGER; + goto end; + } + } - /* Inform the notification thread */ + /* + * A reference to the trigger is acquired by the notification thread. + * It is safe to return the same trigger to the caller since it the + * other user holds a reference. + * + * The trigger is modified during the execution of the + * "register trigger" command. However, by the time the command returns, + * it is safe to use without any locking as its properties are + * immutable. + */ ret = notification_thread_command_register_trigger(notification_thread, trigger); + if (ret != LTTNG_OK) { + goto end_notification_thread; + } + + /* Return an updated trigger to the client. */ + *return_trigger = trigger; + +end_notification_thread: /* Ownership of trigger was transferred. */ trigger = NULL; end: @@ -4337,8 +4379,8 @@ int cmd_unregister_trigger(struct command_ctx *cmd_ctx, int sock, struct lttng_trigger *trigger = NULL; struct lttng_payload trigger_payload; struct lttng_credentials cmd_creds = { - .uid = cmd_ctx->creds.uid, - .gid = cmd_ctx->creds.gid, + .uid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.uid), + .gid = LTTNG_OPTIONAL_INIT_VALUE(cmd_ctx->creds.gid), }; lttng_payload_init(&trigger_payload); @@ -4385,7 +4427,20 @@ int cmd_unregister_trigger(struct command_ctx *cmd_ctx, int sock, } } - lttng_trigger_set_credentials(trigger, &cmd_creds); + /* + * Validate the trigger credentials against the command credentials. + * Only the root user can unregister a trigger with non-matching + * credentials. + */ + if (!lttng_credentials_is_equal_uid( + lttng_trigger_get_credentials(trigger), + &cmd_creds)) { + if (lttng_credentials_get_uid(&cmd_creds) != 0) { + ERR("Trigger credentials do not match the command credentials"); + ret = LTTNG_ERR_INVALID_TRIGGER; + goto end; + } + } ret = notification_thread_command_unregister_trigger(notification_thread, trigger); @@ -4395,6 +4450,29 @@ end: return ret; } +int cmd_list_triggers(struct command_ctx *cmd_ctx, + struct notification_thread_handle *notification_thread, + struct lttng_triggers **return_triggers) +{ + int ret = 0; + enum lttng_error_code ret_code; + struct lttng_triggers *triggers = NULL; + + /* Get the set of triggers from the notification thread. */ + ret_code = notification_thread_command_list_triggers( + notification_thread, cmd_ctx->creds.uid, &triggers); + if (ret_code != LTTNG_OK) { + ret = ret_code; + goto end; + } + + *return_triggers = triggers; + triggers = NULL; + ret = LTTNG_OK; +end: + lttng_triggers_destroy(triggers); + return ret; +} /* * Send relayd sockets from snapshot output to consumer. Ignore request if the * snapshot output is *not* set with a remote destination.