From: Jonathan Rajotte Date: Fri, 10 Nov 2017 16:06:41 +0000 (-0500) Subject: Fix: fd of an elf object must be registered to the fd tracker X-Git-Tag: v2.10.1~3 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=4fc6ea30d63cc600f70b5a8aa5ed70fc52ccadf3;p=lttng-ust.git Fix: fd of an elf object must be registered to the fd tracker The open call take place inside ust, it must be tracked to prevent external closing. The bug can be hit during tracing of an application for which the probe provider is loaded using LD_PRELOAD in combination with the fd utility shared object. The application is responsible for closing all possible fd. Signed-off-by: Jonathan Rajotte Signed-off-by: Mathieu Desnoyers --- diff --git a/liblttng-ust/lttng-ust-elf.c b/liblttng-ust/lttng-ust-elf.c index a496841a..f2c09829 100644 --- a/liblttng-ust/lttng-ust-elf.c +++ b/liblttng-ust/lttng-ust-elf.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "lttng-tracer-core.h" #define BUF_LEN 4096 @@ -248,15 +249,20 @@ struct lttng_ust_elf *lttng_ust_elf_create(const char *path) goto error; } + elf->path = strdup(path); if (!elf->path) { goto error; } + lttng_ust_lock_fd_tracker(); elf->fd = open(elf->path, O_RDONLY | O_CLOEXEC); if (elf->fd < 0) { + lttng_ust_unlock_fd_tracker(); goto error; } + lttng_ust_add_fd_to_tracker(elf->fd); + lttng_ust_unlock_fd_tracker(); if (lttng_ust_read(elf->fd, e_ident, EI_NIDENT) < EI_NIDENT) { goto error; @@ -309,16 +315,7 @@ struct lttng_ust_elf *lttng_ust_elf_create(const char *path) return elf; error: - if (elf) { - free(elf->ehdr); - if (elf->fd >= 0) { - if (close(elf->fd)) { - abort(); - } - } - free(elf->path); - free(elf); - } + lttng_ust_elf_destroy(elf); return NULL; } @@ -339,14 +336,25 @@ uint8_t lttng_ust_elf_is_pic(struct lttng_ust_elf *elf) */ void lttng_ust_elf_destroy(struct lttng_ust_elf *elf) { + int ret; + if (!elf) { return; } - free(elf->ehdr); - if (close(elf->fd)) { - abort(); + if (elf->fd >= 0) { + lttng_ust_lock_fd_tracker(); + ret = close(elf->fd); + if (!ret) { + lttng_ust_delete_fd_from_tracker(elf->fd); + } else { + PERROR("close"); + abort(); + } + lttng_ust_unlock_fd_tracker(); } + + free(elf->ehdr); free(elf->path); free(elf); }