Fix: agent port file is o+w when launching as root
[lttng-tools.git] / src / common / shm.c
index 737f73e084706b270ace9bf4781fd04211fee71e..a6497850c6b53bf783705ff2a256137c350f568a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2011 EfficiOS Inc.
  * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  *
  * SPDX-License-Identifier: GPL-2.0-only
@@ -21,8 +21,7 @@
 #include "shm.h"
 
 /*
- * Using fork to set umask in the child process (not multi-thread safe). We
- * deal with the shm_open vs ftruncate race (happening when the sessiond owns
+ * We deal with the shm_open vs ftruncate race (happening when the sessiond owns
  * the shm and does not let everybody modify it, to ensure safety against
  * shm_unlink) by simply letting the mmap fail and retrying after a few
  * seconds. For global shm, everybody has rw access to it until the sessiond
@@ -31,7 +30,7 @@
 static int get_wait_shm(char *shm_path, size_t mmap_size, int global)
 {
        int wait_shm_fd, ret;
-       mode_t mode;
+       mode_t mode, old_mode;
 
        assert(shm_path);
 
@@ -51,11 +50,7 @@ static int get_wait_shm(char *shm_path, size_t mmap_size, int global)
                mode |= S_IROTH | S_IWOTH;
        }
 
-       /*
-        * We're alone in a child process, so we can modify the process-wide
-        * umask.
-        */
-       umask(~mode);
+       old_mode = umask(~mode);
 
        /*
         * Try creating shm (or get rw access). We don't do an exclusive open,
@@ -95,22 +90,24 @@ static int get_wait_shm(char *shm_path, size_t mmap_size, int global)
                        wait_shm_fd = shm_open(shm_path, O_RDWR, mode);
                }
                if (wait_shm_fd < 0) {
-                       PERROR("Failed to open wait shm at %s", shm_path);
+                       PERROR("Failed to open \"wait\" shared memory object: path = '%s'", shm_path);
                        goto error;
                }
        }
 
        ret = ftruncate(wait_shm_fd, mmap_size);
        if (ret < 0) {
-               PERROR("ftruncate wait shm");
-               exit(EXIT_FAILURE);
+               PERROR("Failed to truncate \"wait\" shared memory object: fd = %d, size = %zu",
+                               wait_shm_fd, mmap_size);
+               goto error;
        }
 
        if (global) {
                ret = fchown(wait_shm_fd, 0, 0);
                if (ret < 0) {
-                       PERROR("fchown");
-                       exit(EXIT_FAILURE);
+                       PERROR("Failed to set ownership of \"wait\" shared memory object: fd = %d, owner = 0, group = 0",
+                                       wait_shm_fd);
+                       goto error;
                }
                /*
                 * If global session daemon, any application can
@@ -120,25 +117,37 @@ static int get_wait_shm(char *shm_path, size_t mmap_size, int global)
                mode &= ~S_IWOTH;
                ret = fchmod(wait_shm_fd, mode);
                if (ret < 0) {
-                       PERROR("fchmod");
-                       exit(EXIT_FAILURE);
+                       PERROR("Failed to set the mode of the \"wait\" shared memory object: fd = %d, mode = %d",
+                                       wait_shm_fd, mode);
+                       goto error;
                }
        } else {
                ret = fchown(wait_shm_fd, getuid(), getgid());
                if (ret < 0) {
-                       PERROR("fchown");
-                       exit(EXIT_FAILURE);
+                       PERROR("Failed to set ownership of \"wait\" shared memory object: fd = %d, owner = %d, group = %d",
+                                       wait_shm_fd, getuid(), getgid());
+                       goto error;
                }
        }
 
-       DBG("Got the wait shm fd %d", wait_shm_fd);
+       DBG("Wait shared memory file descriptor created successfully: path = '%s', mmap_size = %zu, global = %s, fd = %d",
+                       shm_path, mmap_size, global ? "true" : "false",
+                       wait_shm_fd);
 
+end:
+       (void) umask(old_mode);
        return wait_shm_fd;
 
 error:
        DBG("Failing to get the wait shm fd");
+       if (wait_shm_fd >= 0) {
+               if (close(wait_shm_fd)) {
+                       PERROR("Failed to close wait shm file descriptor during error handling");
+               }
+       }
 
-       return -1;
+       wait_shm_fd = -1;
+       goto end;
 }
 
 /*
@@ -149,6 +158,7 @@ error:
  * This returned value is used by futex_wait_update() in futex.c to WAKE all
  * waiters which are UST application waiting for a session daemon.
  */
+LTTNG_HIDDEN
 char *shm_ust_get_mmap(char *shm_path, int global)
 {
        size_t mmap_size;
@@ -160,7 +170,7 @@ char *shm_ust_get_mmap(char *shm_path, int global)
 
        sys_page_size = sysconf(_SC_PAGE_SIZE);
        if (sys_page_size < 0) {
-               PERROR("sysconf PAGE_SIZE");
+               PERROR("Failed to get PAGE_SIZE of system");
                goto error;
        }
        mmap_size = sys_page_size;
@@ -176,11 +186,13 @@ char *shm_ust_get_mmap(char *shm_path, int global)
        /* close shm fd immediately after taking the mmap reference */
        ret = close(wait_shm_fd);
        if (ret) {
-               PERROR("Error closing fd");
+               PERROR("Failed to close \"wait\" shared memory object file descriptor: fd = %d",
+                               wait_shm_fd);
        }
 
        if (wait_shm_mmap == MAP_FAILED) {
-               DBG("mmap error (can be caused by race with ust).");
+               DBG("Failed to mmap the \"wait\" shareed memory object (can be caused by race with ust): path = '%s', global = %s",
+                               shm_path, global ? "true" : "false");
                goto error;
        }
 
@@ -193,6 +205,7 @@ error:
 /*
  * shm_create_anonymous is never called concurrently within a process.
  */
+LTTNG_HIDDEN
 int shm_create_anonymous(const char *owner_name)
 {
        char tmp_name[NAME_MAX];
@@ -200,29 +213,35 @@ int shm_create_anonymous(const char *owner_name)
 
        ret = snprintf(tmp_name, NAME_MAX, "/shm-%s-%d", owner_name, getpid());
        if (ret < 0) {
-               PERROR("snprintf");
+               PERROR("Failed to format shm path: owner_name = '%s', pid = %d",
+                               owner_name, getpid());
                return -1;
        }
+
        /*
         * Allocate shm, and immediately unlink its shm oject, keeping only the
         * file descriptor as a reference to the object.
         */
        shmfd = shm_open(tmp_name, O_CREAT | O_EXCL | O_RDWR, 0700);
        if (shmfd < 0) {
-               PERROR("shm_open");
+               PERROR("Failed to open shared memory object: path = '%s'", tmp_name);
                goto error_shm_open;
        }
+
        ret = shm_unlink(tmp_name);
        if (ret < 0 && errno != ENOENT) {
-               PERROR("shm_unlink");
+               PERROR("Failed to unlink shared memory object: path = '%s'",
+                               tmp_name);
                goto error_shm_release;
        }
+
        return shmfd;
 
 error_shm_release:
        ret = close(shmfd);
        if (ret) {
-               PERROR("close");
+               PERROR("Failed to close shared memory object file descriptor: fd = %d, path = '%s'",
+                               shmfd, tmp_name);
        }
 error_shm_open:
        return -1;
This page took 0.026245 seconds and 4 git commands to generate.