Fix: fd-tracker: error path lead to null dereference of handle
[lttng-tools.git] / src / common / fd-tracker / fd-tracker.c
index c8cbc6b33dc4545f8d2f4e998961a6d4ef90b204..acbee670a0acdf4086853a98460b7f923f0e444d 100644 (file)
@@ -475,6 +475,8 @@ int fd_tracker_destroy(struct fd_tracker *tracker)
                ret = cds_lfht_destroy(tracker->unsuspendable_fds, NULL);
                assert(!ret);
        }
+
+       lttng_inode_registry_destroy(tracker->inode_registry);
        pthread_mutex_destroy(&tracker->lock);
        free(tracker);
 end:
@@ -498,18 +500,17 @@ struct fs_handle *fd_tracker_open_fs_handle(struct fd_tracker *tracker,
                if (tracker->count.suspendable.active > 0) {
                        ret = fd_tracker_suspend_handles(tracker, 1);
                        if (ret) {
-                               goto error_destroy;
+                               goto end;
                        }
                } else {
                        /*
                         * There are not enough active suspendable file
-                        * descriptors to open a new fd and still accomodate the
-                        * tracker's capacity.
+                        * descriptors to open a new fd and still accommodate
+                        * the tracker's capacity.
                         */
                        WARN("Cannot open file system handle, too many unsuspendable file descriptors are opened (%u)",
                                        tracker->count.unsuspendable);
-                       ret = -EMFILE;
-                       goto error_destroy;
+                       goto end;
                }
        }
 
@@ -517,19 +518,18 @@ struct fs_handle *fd_tracker_open_fs_handle(struct fd_tracker *tracker,
        if (!handle) {
                goto end;
        }
+       handle->tracker = tracker;
 
        ret = pthread_mutex_init(&handle->lock, NULL);
        if (ret) {
                PERROR("Failed to initialize handle mutex while creating fs handle");
-               free(handle);
-               goto end;
+               goto error_mutex_init;
        }
 
        handle->fd = open_from_properties(path, &properties);
        if (handle->fd < 0) {
                PERROR("Failed to open fs handle to %s, open() returned", path);
-               ret = -errno;
-               goto error_destroy;
+               goto error;
        }
 
        handle->properties = properties;
@@ -539,24 +539,26 @@ struct fs_handle *fd_tracker_open_fs_handle(struct fd_tracker *tracker,
        if (!handle->inode) {
                ERR("Failed to get lttng_inode corresponding to file %s",
                                path);
-               goto error_destroy;
+               goto error;
        }
 
        if (fstat(handle->fd, &fd_stat)) {
                PERROR("Failed to retrieve file descriptor inode while creating fs handle, fstat() returned");
-               ret = -errno;
-               goto error_destroy;
+               goto error;
        }
        handle->ino = fd_stat.st_ino;
 
        fd_tracker_track(tracker, handle);
-       handle->tracker = tracker;
-       pthread_mutex_unlock(&tracker->lock);
 end:
-       return handle;
-error_destroy:
        pthread_mutex_unlock(&tracker->lock);
-       (void) fs_handle_close(handle);
+       return handle;
+error:
+       if (handle->inode) {
+               lttng_inode_put(handle->inode);
+       }
+       pthread_mutex_destroy(&handle->lock);
+error_mutex_init:
+       free(handle);
        handle = NULL;
        goto end;
 }
@@ -844,7 +846,7 @@ int fs_handle_unlink(struct fs_handle *handle)
 int fs_handle_close(struct fs_handle *handle)
 {
        int ret = 0;
-       const char *path;
+       const char *path = NULL;
 
        if (!handle) {
                ret = -EINVAL;
@@ -853,7 +855,9 @@ int fs_handle_close(struct fs_handle *handle)
 
        pthread_mutex_lock(&handle->tracker->lock);
        pthread_mutex_lock(&handle->lock);
-       path = lttng_inode_get_path(handle->inode);
+       if (handle->inode) {
+               path = lttng_inode_get_path(handle->inode);
+       }
        fd_tracker_untrack(handle->tracker, handle);
        if (handle->fd >= 0) {
                /*
@@ -862,7 +866,7 @@ int fs_handle_close(struct fs_handle *handle)
                 */
                if (close(handle->fd)) {
                        PERROR("Failed to close the file descritptor (%d) of fs handle to %s, close() returned",
-                                       handle->fd, path);
+                                       handle->fd, path ? path : "Unknown");
                }
                handle->fd = -1;
        }
This page took 0.024515 seconds and 4 git commands to generate.