X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;ds=sidebyside;f=libringbuffer%2Fshm.c;h=0d92572d7b5b6170d79ed7e457e115bba957b7ef;hb=5a61337d8b92f7419e58e5b46ffc4f75ac6269af;hp=e1dd56f91d0b06afb293a9d8bd601fc158e72845;hpb=dc613eb9d0c449f3e988af66b173abefa4b22233;p=lttng-ust.git diff --git a/libringbuffer/shm.c b/libringbuffer/shm.c index e1dd56f9..0d92572d 100644 --- a/libringbuffer/shm.c +++ b/libringbuffer/shm.c @@ -13,6 +13,9 @@ #include /* For mode constants */ #include /* For O_* constants */ #include +#include +#include +#include #include struct shm_object_table *shm_object_table_create(size_t max_nb_obj) @@ -28,9 +31,11 @@ struct shm_object_table *shm_object_table_create(size_t max_nb_obj) struct shm_object *shm_object_table_append(struct shm_object_table *table, size_t memory_map_size) { - int shmfd, waitfd[2], ret, i; + int shmfd, waitfd[2], ret, i, sigblocked = 0; struct shm_object *obj; char *memory_map; + char tmp_name[NAME_MAX] = "ust-shm-tmp-XXXXXX"; + sigset_t all_sigs, orig_sigs; if (table->allocated_len >= table->size) return NULL; @@ -59,6 +64,19 @@ struct shm_object *shm_object_table_append(struct shm_object_table *table, /* shm_fd: create shm */ + /* + * Theoretically, we could leak a shm if the application crashes + * between open and unlink. Disable signals on this thread for + * increased safety against this scenario. + */ + sigfillset(&all_sigs); + ret = pthread_sigmask(SIG_BLOCK, &all_sigs, &orig_sigs); + if (ret == -1) { + PERROR("pthread_sigmask"); + goto error_pthread_sigmask; + } + sigblocked = 1; + /* * Allocate shm, and immediately unlink its shm oject, keeping * only the file descriptor as a reference to the object. If it @@ -69,17 +87,32 @@ struct shm_object *shm_object_table_append(struct shm_object_table *table, * the process (POSIX leaves this implementation-defined). */ do { - shmfd = shm_open("ust-shm-tmp", + /* + * Using mktemp filename with O_CREAT | O_EXCL open + * flags. + */ + mktemp(tmp_name); + if (tmp_name[0] == '\0') { + PERROR("mktemp"); + goto error_shm_open; + } + shmfd = shm_open(tmp_name, O_CREAT | O_EXCL | O_RDWR, 0700); - } while (shmfd < 0 && errno == EEXIST); + } while (shmfd < 0 && (errno == EEXIST || errno == EACCES)); if (shmfd < 0) { PERROR("shm_open"); goto error_shm_open; } - ret = shm_unlink("ust-shm-tmp"); - if (ret) { + ret = shm_unlink(tmp_name); + if (ret < 0 && errno != ENOENT) { PERROR("shm_unlink"); - goto error_unlink; + goto error_shm_release; + } + sigblocked = 0; + ret = pthread_sigmask(SIG_SETMASK, &orig_sigs, NULL); + if (ret == -1) { + PERROR("pthread_sigmask"); + goto error_sigmask_release; } ret = ftruncate(shmfd, memory_map_size); if (ret) { @@ -104,13 +137,21 @@ struct shm_object *shm_object_table_append(struct shm_object_table *table, error_mmap: error_ftruncate: -error_unlink: +error_shm_release: +error_sigmask_release: ret = close(shmfd); if (ret) { PERROR("close"); assert(0); } error_shm_open: + if (sigblocked) { + ret = pthread_sigmask(SIG_SETMASK, &orig_sigs, NULL); + if (ret == -1) { + PERROR("pthread_sigmask"); + } + } +error_pthread_sigmask: error_fcntl: for (i = 0; i < 2; i++) { ret = close(waitfd[i]); @@ -120,7 +161,6 @@ error_fcntl: } } error_pipe: - free(obj); return NULL; }