Fix: leak of trace_path on error in ust_app_snapshot_record
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index d2edfd5ce4248062457432ff123498b582a9dfba..66b50eb43df98ea42c0700c5cedd5e9f28e17e8b 100644 (file)
@@ -1832,15 +1832,12 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan,
 static void shadow_copy_session(struct ust_app_session *ua_sess,
                struct ltt_ust_session *usess, struct ust_app *app)
 {
-       time_t rawtime;
        struct tm *timeinfo;
        char datetime[16];
        int ret;
        char tmp_shm_path[PATH_MAX];
 
-       /* Get date and time for unique app path */
-       time(&rawtime);
-       timeinfo = localtime(&rawtime);
+       timeinfo = localtime(&app->registration_time);
        strftime(datetime, sizeof(datetime), "%Y%m%d-%H%M%S", timeinfo);
 
        DBG2("Shadow copy of session handle %d", ua_sess->handle);
@@ -1996,7 +1993,8 @@ static int setup_buffer_reg_pid(struct ust_app_session *ua_sess,
                        app->byte_order, app->version.major, app->version.minor,
                        reg_pid->root_shm_path, reg_pid->shm_path,
                        ua_sess->effective_credentials.uid,
-                       ua_sess->effective_credentials.gid);
+                       ua_sess->effective_credentials.gid, ua_sess->tracing_id,
+                       app->uid);
        if (ret < 0) {
                /*
                 * reg_pid->registry->reg.ust is NULL upon error, so we need to
@@ -2063,7 +2061,8 @@ static int setup_buffer_reg_uid(struct ltt_ust_session *usess,
                        app->uint64_t_alignment, app->long_alignment,
                        app->byte_order, app->version.major,
                        app->version.minor, reg_uid->root_shm_path,
-                       reg_uid->shm_path, usess->uid, usess->gid);
+                       reg_uid->shm_path, usess->uid, usess->gid,
+                       ua_sess->tracing_id, app->uid);
        if (ret < 0) {
                /*
                 * reg_uid->registry->reg.ust is NULL upon error, so we need to
@@ -3377,6 +3376,8 @@ void ust_app_add(struct ust_app *app)
        assert(app);
        assert(app->notify_sock >= 0);
 
+       app->registration_time = time(NULL);
+
        rcu_read_lock();
 
        /*
@@ -5877,14 +5878,14 @@ void ust_app_destroy(struct ust_app *app)
  */
 enum lttng_error_code ust_app_snapshot_record(
                const struct ltt_ust_session *usess,
-               const struct snapshot_output *output, int wait,
+               const struct consumer_output *output, int wait,
                uint64_t nb_packets_per_stream)
 {
        int ret = 0;
        enum lttng_error_code status = LTTNG_OK;
        struct lttng_ht_iter iter;
        struct ust_app *app;
-       char pathname[PATH_MAX];
+       char *trace_path = NULL;
 
        assert(usess);
        assert(output);
@@ -5899,6 +5900,7 @@ enum lttng_error_code ust_app_snapshot_record(
                cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) {
                        struct buffer_reg_channel *reg_chan;
                        struct consumer_socket *socket;
+                       char pathname[PATH_MAX];
 
                        if (!reg->registry->reg.ust->metadata_key) {
                                /* Skip since no metadata is present */
@@ -5926,14 +5928,20 @@ enum lttng_error_code ust_app_snapshot_record(
                                status = LTTNG_ERR_INVALID;
                                goto error;
                        }
-
+                       /* Free path allowed on previous iteration. */
+                       free(trace_path);
+                       trace_path = setup_channel_trace_path(usess->consumer, pathname);
+                       if (!trace_path) {
+                               status = LTTNG_ERR_INVALID;
+                               goto error;
+                       }
                         /* Add the UST default trace dir to path. */
                        cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter,
                                        reg_chan, node.node) {
                                status = consumer_snapshot_channel(socket,
                                                reg_chan->consumer_key,
                                                output, 0, usess->uid,
-                                               usess->gid, pathname, wait,
+                                               usess->gid, trace_path, wait,
                                                nb_packets_per_stream);
                                if (status != LTTNG_OK) {
                                        goto error;
@@ -5941,7 +5949,7 @@ enum lttng_error_code ust_app_snapshot_record(
                        }
                        status = consumer_snapshot_channel(socket,
                                        reg->registry->reg.ust->metadata_key, output, 1,
-                                       usess->uid, usess->gid, pathname, wait, 0);
+                                       usess->uid, usess->gid, trace_path, wait, 0);
                        if (status != LTTNG_OK) {
                                goto error;
                        }
@@ -5956,6 +5964,7 @@ enum lttng_error_code ust_app_snapshot_record(
                        struct ust_app_channel *ua_chan;
                        struct ust_app_session *ua_sess;
                        struct ust_registry_session *registry;
+                       char pathname[PATH_MAX];
 
                        ua_sess = lookup_session_by_app(usess, app);
                        if (!ua_sess) {
@@ -5965,7 +5974,7 @@ enum lttng_error_code ust_app_snapshot_record(
 
                        /* Get the right consumer socket for the application. */
                        socket = consumer_find_socket_by_bitness(app->bits_per_long,
-                                       output->consumer);
+                                       output);
                        if (!socket) {
                                status = LTTNG_ERR_INVALID;
                                goto error;
@@ -5980,7 +5989,13 @@ enum lttng_error_code ust_app_snapshot_record(
                                PERROR("snprintf snapshot path");
                                goto error;
                        }
-
+                       /* Free path allowed on previous iteration. */
+                       free(trace_path);
+                       trace_path = setup_channel_trace_path(usess->consumer, pathname);
+                       if (!trace_path) {
+                               status = LTTNG_ERR_INVALID;
+                               goto error;
+                       }
                         cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter,
                                        ua_chan, node.node) {
                                status = consumer_snapshot_channel(socket,
@@ -5989,7 +6004,7 @@ enum lttng_error_code ust_app_snapshot_record(
                                                                .uid,
                                                ua_sess->effective_credentials
                                                                .gid,
-                                               pathname, wait,
+                                               trace_path, wait,
                                                nb_packets_per_stream);
                                switch (status) {
                                case LTTNG_OK:
@@ -6010,7 +6025,7 @@ enum lttng_error_code ust_app_snapshot_record(
                                        registry->metadata_key, output, 1,
                                        ua_sess->effective_credentials.uid,
                                        ua_sess->effective_credentials.gid,
-                                       pathname, wait, 0);
+                                       trace_path, wait, 0);
                        switch (status) {
                        case LTTNG_OK:
                                break;
@@ -6028,6 +6043,7 @@ enum lttng_error_code ust_app_snapshot_record(
        }
 
 error:
+       free(trace_path);
        rcu_read_unlock();
        return status;
 }
This page took 0.025662 seconds and 4 git commands to generate.