X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=libringbuffer%2Fshm.c;h=0d92572d7b5b6170d79ed7e457e115bba957b7ef;hb=5a61337d8b92f7419e58e5b46ffc4f75ac6269af;hp=6a77af6462a61d93a3c5c1bfb8fff214f546de62;hpb=5d61a504c6d395914d78f97e82f6fd0fdf0f98a0;p=deliverable%2Flttng-ust.git diff --git a/libringbuffer/shm.c b/libringbuffer/shm.c index 6a77af64..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,13 +31,15 @@ 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; - obj = &table->objects[table->allocated_len++]; + obj = &table->objects[table->allocated_len]; /* wait_fd: create pipe */ ret = pipe(waitfd); @@ -55,10 +60,23 @@ struct shm_object *shm_object_table_append(struct shm_object_table *table, PERROR("fcntl"); goto error_fcntl; } - *obj->wait_fd = *waitfd; + memcpy(obj->wait_fd, waitfd, sizeof(waitfd)); /* 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,17 +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++; + 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]); @@ -118,7 +161,6 @@ error_fcntl: } } error_pipe: - free(obj); return NULL; }