Fix: Buggy string comparison in ust registry ht_match_event
[lttng-tools.git] / src / bin / lttng-sessiond / ust-registry.c
index 8c3d08d825c5568255ece6295d0b6be1dc2aa2a4..3f1390dc3df1e65449700c12fa502215a9e29426 100644 (file)
@@ -15,6 +15,7 @@
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 #define _GNU_SOURCE
+#define _LGPL_SOURCE
 #include <assert.h>
 #include <inttypes.h>
 
@@ -42,13 +43,13 @@ static int ht_match_event(struct cds_lfht_node *node, const void *_key)
        key = _key;
 
        /* It has to be a perfect match. */
-       if (strncmp(event->name, key->name, sizeof(event->name)) != 0) {
+       if (strncmp(event->name, key->name, sizeof(event->name))) {
                goto no_match;
        }
 
        /* It has to be a perfect match. */
        if (strncmp(event->signature, key->signature,
-                               strlen(event->signature) != 0)) {
+                       strlen(event->signature))) {
                goto no_match;
        }
 
@@ -545,7 +546,11 @@ int ust_registry_session_init(struct ust_registry_session **sessionp,
                uint32_t long_alignment,
                int byte_order,
                uint32_t major,
-               uint32_t minor)
+               uint32_t minor,
+               const char *root_shm_path,
+               const char *shm_path,
+               uid_t euid,
+               gid_t egid)
 {
        int ret;
        struct ust_registry_session *session;
@@ -566,6 +571,43 @@ int ust_registry_session_init(struct ust_registry_session **sessionp,
        session->uint64_t_alignment = uint64_t_alignment;
        session->long_alignment = long_alignment;
        session->byte_order = byte_order;
+       session->metadata_fd = -1;
+       session->uid = euid;
+       session->gid = egid;
+       strncpy(session->root_shm_path, root_shm_path,
+               sizeof(session->root_shm_path));
+       session->root_shm_path[sizeof(session->root_shm_path) - 1] = '\0';
+       if (shm_path[0]) {
+               strncpy(session->shm_path, shm_path,
+                       sizeof(session->shm_path));
+               session->shm_path[sizeof(session->shm_path) - 1] = '\0';
+               strncpy(session->metadata_path, shm_path,
+                       sizeof(session->metadata_path));
+               session->metadata_path[sizeof(session->metadata_path) - 1] = '\0';
+               strncat(session->metadata_path, "/metadata",
+                       sizeof(session->metadata_path)
+                               - strlen(session->metadata_path) - 1);
+       }
+       if (session->shm_path[0]) {
+               ret = run_as_mkdir_recursive(session->shm_path,
+                       S_IRWXU | S_IRWXG,
+                       euid, egid);
+               if (ret) {
+                       PERROR("run_as_mkdir_recursive");
+                       goto error;
+               }
+       }
+       if (session->metadata_path[0]) {
+               /* Create metadata file */
+               ret = run_as_open(session->metadata_path,
+                       O_WRONLY | O_CREAT | O_EXCL,
+                       S_IRUSR | S_IWUSR, euid, egid);
+               if (ret < 0) {
+                       PERROR("Opening metadata file");
+                       goto error;
+               }
+               session->metadata_fd = ret;
+       }
 
        session->channels = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
        if (!session->channels) {
@@ -607,20 +649,45 @@ void ust_registry_session_destroy(struct ust_registry_session *reg)
        struct lttng_ht_iter iter;
        struct ust_registry_channel *chan;
 
+       if (!reg) {
+               return;
+       }
+
        /* On error, EBUSY can be returned if lock. Code flow error. */
        ret = pthread_mutex_destroy(&reg->lock);
        assert(!ret);
 
-       rcu_read_lock();
-       /* Destroy all event associated with this registry. */
-       cds_lfht_for_each_entry(reg->channels->ht, &iter.iter, chan, node.node) {
-               /* Delete the node from the ht and free it. */
-               ret = lttng_ht_del(reg->channels, &iter);
-               assert(!ret);
-               destroy_channel(chan);
+       if (reg->channels) {
+               rcu_read_lock();
+               /* Destroy all event associated with this registry. */
+               cds_lfht_for_each_entry(reg->channels->ht, &iter.iter, chan,
+                               node.node) {
+                       /* Delete the node from the ht and free it. */
+                       ret = lttng_ht_del(reg->channels, &iter);
+                       assert(!ret);
+                       destroy_channel(chan);
+               }
+               rcu_read_unlock();
+               ht_cleanup_push(reg->channels);
        }
-       rcu_read_unlock();
 
-       ht_cleanup_push(reg->channels);
        free(reg->metadata);
+       if (reg->metadata_fd >= 0) {
+               ret = close(reg->metadata_fd);
+               if (ret) {
+                       PERROR("close");
+               }
+               ret = run_as_unlink(reg->metadata_path,
+                               reg->uid, reg->gid);
+               if (ret) {
+                       PERROR("unlink");
+               }
+       }
+       if (reg->root_shm_path[0]) {
+               /*
+                * Try deleting the directory hierarchy.
+                */
+               (void) run_as_recursive_rmdir(reg->root_shm_path,
+                               reg->uid, reg->gid);
+       }
 }
This page took 0.024739 seconds and 4 git commands to generate.