X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Flttng-ctl.c;h=001abffcd925705fbcee43a613ed055e2cea50c7;hp=4eb36a2612d952bb71d38e9cedcc4d70a47d6148;hb=3e6e0df2f8f9f23d252c2508b6d741916dfcc4b3;hpb=e4d2f27a74baf6942ac8fcafd5ea53e775ceceb3 diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 4eb36a261..001abffcd 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -13,13 +13,13 @@ #define _LGPL_SOURCE #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -2243,7 +2243,7 @@ int lttng_list_events(struct lttng_handle *handle, cmd_header_view = lttng_buffer_view_from_dynamic_buffer( &payload.buffer, 0, sizeof(*cmd_header)); - if (!cmd_header_view.data) { + if (!lttng_buffer_view_is_valid(&cmd_header_view)) { ret = -LTTNG_ERR_INVALID_PROTOCOL; goto end; } @@ -2310,6 +2310,11 @@ int lttng_list_events(struct lttng_handle *handle, payload_view.buffer.data, ext_comm->userspace_probe_location_len); + if (!lttng_payload_view_is_valid(&probe_location_view)) { + ret = -LTTNG_ERR_PROBE_LOCATION_INVAL; + goto end; + } + /* * Create a temporary userspace probe location * to determine the size needed by a "flattened" @@ -2449,6 +2454,11 @@ int lttng_list_events(struct lttng_handle *handle, payload_copy_view.buffer.data, ext_comm->userspace_probe_location_len); + if (!lttng_payload_view_is_valid(&probe_location_view)) { + ret = -LTTNG_ERR_PROBE_LOCATION_INVAL; + goto free_dynamic_buffer; + } + ret = lttng_userspace_probe_location_create_from_payload( &probe_location_view, &probe_location); @@ -2956,6 +2966,12 @@ int lttng_register_trigger(struct lttng_trigger *trigger) struct lttcomm_session_msg *message_lsm; struct lttng_payload message; struct lttng_payload reply; + struct lttng_trigger *reply_trigger = NULL; + const struct lttng_credentials user_creds = { + .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()), + .gid = LTTNG_OPTIONAL_INIT_UNSET, + }; + lttng_payload_init(&message); lttng_payload_init(&reply); @@ -2965,12 +2981,41 @@ int lttng_register_trigger(struct lttng_trigger *trigger) goto end; } + if (!trigger->creds.uid.is_set) { + /* Use the client's credentials as the trigger credentials. */ + lttng_trigger_set_credentials(trigger, &user_creds); + } else { + /* + * Validate that either the current trigger credentials and the + * client credentials are identical or that the current user is + * root. The root user can register, unregister triggers for + * himself and other users. + * + * This check is also present on the sessiond side, using the + * credentials passed on the socket. These check are all + * "safety" checks. + */ + const struct lttng_credentials *trigger_creds = + lttng_trigger_get_credentials(trigger); + + if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) { + if (lttng_credentials_get_uid(&user_creds) != 0) { + ret = -LTTNG_ERR_EPERM; + goto end; + } + } + } + if (!lttng_trigger_validate(trigger)) { ret = -LTTNG_ERR_INVALID_TRIGGER; goto end; } - lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm)); + ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm)); + if (ret) { + ret = -LTTNG_ERR_NOMEM; + goto end; + } /* * This is needed to populate the trigger object size for the command @@ -2999,10 +3044,30 @@ int lttng_register_trigger(struct lttng_trigger *trigger) } } + { + struct lttng_payload_view reply_view = + lttng_payload_view_from_payload( + &reply, 0, reply.buffer.size); + + ret = lttng_trigger_create_from_payload( + &reply_view, &reply_trigger); + if (ret < 0) { + ret = -LTTNG_ERR_FATAL; + goto end; + } + } + + ret = lttng_trigger_assign_name(trigger, reply_trigger); + if (ret < 0) { + ret = -LTTNG_ERR_FATAL; + goto end; + } + ret = 0; end: lttng_payload_reset(&message); lttng_payload_reset(&reply); + lttng_trigger_destroy(reply_trigger); return ret; } @@ -3013,6 +3078,10 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) struct lttcomm_session_msg *message_lsm; struct lttng_payload message; struct lttng_payload reply; + const struct lttng_credentials user_creds = { + .uid = LTTNG_OPTIONAL_INIT_VALUE(geteuid()), + .gid = LTTNG_OPTIONAL_INIT_UNSET, + }; lttng_payload_init(&message); lttng_payload_init(&reply); @@ -3022,6 +3091,31 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) goto end; } + if (!trigger->creds.uid.is_set) { + /* Use the client's credentials as the trigger credentials. */ + lttng_trigger_set_credentials(trigger, &user_creds); + } else { + /* + * Validate that either the current trigger credentials and the + * client credentials are identical or that the current user is + * root. The root user can register, unregister triggers for + * himself and other users. + * + * This check is also present on the sessiond side, using the + * credentials passed on the socket. These check are all + * "safety" checks. + */ + const struct lttng_credentials *trigger_creds = + lttng_trigger_get_credentials(trigger); + + if (!lttng_credentials_is_equal_uid(trigger_creds, &user_creds)) { + if (lttng_credentials_get_uid(&user_creds) != 0) { + ret = -LTTNG_ERR_EPERM; + goto end; + } + } + } + if (!lttng_trigger_validate(trigger)) { ret = -LTTNG_ERR_INVALID_TRIGGER; goto end; @@ -3030,7 +3124,11 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) memset(&lsm, 0, sizeof(lsm)); lsm.cmd_type = LTTNG_UNREGISTER_TRIGGER; - lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm)); + ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm)); + if (ret) { + ret = -LTTNG_ERR_NOMEM; + goto end; + } /* * This is needed to populate the trigger object size for the command