*/
#define _LGPL_SOURCE
+#include "shm.hpp"
+
+#include <common/error.hpp>
+
#include <fcntl.h>
#include <limits.h>
#include <sys/mman.h>
#include <unistd.h>
#include <urcu.h>
-#include <common/error.h>
-
-#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
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;
LTTNG_ASSERT(shm_path);
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,
if (errno == EACCES) {
/* Work around sysctl fs.protected_regular. */
DBG("shm_open of %s returned EACCES, this may be caused "
- "by the fs.protected_regular sysctl. "
- "Attempting to open the shm without "
- "creating it.", shm_path);
+ "by the fs.protected_regular sysctl. "
+ "Attempting to open the shm without "
+ "creating it.",
+ shm_path);
wait_shm_fd = shm_open(shm_path, O_RDWR, mode);
}
if (wait_shm_fd < 0) {
- PERROR("Failed to open \"wait\" shared memory object: path = '%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("Failed to truncate \"wait\" shared memory object: fd = %d, size = %zu",
- wait_shm_fd, mmap_size);
- exit(EXIT_FAILURE);
+ wait_shm_fd,
+ mmap_size);
+ goto error;
}
if (global) {
ret = fchown(wait_shm_fd, 0, 0);
if (ret < 0) {
PERROR("Failed to set ownership of \"wait\" shared memory object: fd = %d, owner = 0, group = 0",
- wait_shm_fd);
- exit(EXIT_FAILURE);
+ wait_shm_fd);
+ goto error;
}
/*
* If global session daemon, any application can
ret = fchmod(wait_shm_fd, mode);
if (ret < 0) {
PERROR("Failed to set the mode of the \"wait\" shared memory object: fd = %d, mode = %d",
- wait_shm_fd, mode);
- exit(EXIT_FAILURE);
+ wait_shm_fd,
+ mode);
+ goto error;
}
} else {
ret = fchown(wait_shm_fd, getuid(), getgid());
if (ret < 0) {
PERROR("Failed to set ownership of \"wait\" shared memory object: fd = %d, owner = %d, group = %d",
- wait_shm_fd, getuid(), getgid());
- exit(EXIT_FAILURE);
+ wait_shm_fd,
+ getuid(),
+ getgid());
+ goto error;
}
}
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);
+ shm_path,
+ mmap_size,
+ global ? "true" : "false",
+ wait_shm_fd);
+end:
+ (void) umask(old_mode);
return wait_shm_fd;
error:
- DBG("Failed to open shared memory file descriptor: path = '%s', mmap_size = %zu, global = %s",
- shm_path, mmap_size, global ? "true" : "false");
+ 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;
}
/*
goto error;
}
- wait_shm_mmap = (char *) mmap(NULL, mmap_size, PROT_WRITE | PROT_READ,
- MAP_SHARED, wait_shm_fd, 0);
+ wait_shm_mmap =
+ (char *) mmap(NULL, mmap_size, PROT_WRITE | PROT_READ, MAP_SHARED, wait_shm_fd, 0);
/* close shm fd immediately after taking the mmap reference */
ret = close(wait_shm_fd);
if (ret) {
PERROR("Failed to close \"wait\" shared memory object file descriptor: fd = %d",
- wait_shm_fd);
+ wait_shm_fd);
}
if (wait_shm_mmap == MAP_FAILED) {
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");
+ shm_path,
+ global ? "true" : "false");
goto error;
}
ret = snprintf(tmp_name, NAME_MAX, "/shm-%s-%d", owner_name, getpid());
if (ret < 0) {
PERROR("Failed to format shm path: owner_name = '%s', pid = %d",
- owner_name, getpid());
+ owner_name,
+ getpid());
return -1;
}
ret = shm_unlink(tmp_name);
if (ret < 0 && errno != ENOENT) {
- PERROR("Failed to unlink shared memory object: path = '%s'",
- tmp_name);
+ PERROR("Failed to unlink shared memory object: path = '%s'", tmp_name);
goto error_shm_release;
}
ret = close(shmfd);
if (ret) {
PERROR("Failed to close shared memory object file descriptor: fd = %d, path = '%s'",
- shmfd, tmp_name);
+ shmfd,
+ tmp_name);
}
error_shm_open:
return -1;