X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=libringbuffer%2Fshm.c;h=0d92572d7b5b6170d79ed7e457e115bba957b7ef;hb=5a61337d8b92f7419e58e5b46ffc4f75ac6269af;hp=86e8d9184e3c8a3fb066df69e2808028d790fe74;hpb=7a9c21bd702ae4d54d8c1f623e9837e0248b0643;p=lttng-ust.git diff --git a/libringbuffer/shm.c b/libringbuffer/shm.c index 86e8d918..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) { @@ -98,19 +131,27 @@ struct shm_object *shm_object_table_append(struct shm_object_table *table, obj->memory_map = memory_map; obj->memory_map_size = memory_map_size; obj->allocated_len = 0; + obj->index = table->allocated_len++; - table->allocated_len++; return obj; 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; }