X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Flttng-elf.c;h=816dd0d7621a15a3dc6b2f073c2acc9a583fa02a;hp=b2aa88487e1dff286c21d0442f6cdf175a68681f;hb=9ac61dbdc19140c00f345aae570f18abbe079852;hpb=22fae25a70cc5e87ab76e5e2071c88c0c181e2c3 diff --git a/src/common/lttng-elf.c b/src/common/lttng-elf.c index b2aa88487..816dd0d76 100644 --- a/src/common/lttng-elf.c +++ b/src/common/lttng-elf.c @@ -1,21 +1,10 @@ /* - * Copyright (C) 2015 Antoine Busque - * Copyright (C) 2017 Francis Deslauriers - * Copyright (C) 2017 Erica Bugden + * Copyright (C) 2015 Antoine Busque + * Copyright (C) 2017 Francis Deslauriers + * Copyright (C) 2017 Erica Bugden * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * SPDX-License-Identifier: LGPL-2.1-or-later * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -43,6 +32,7 @@ #define NOTE_STAPSDT_SECTION_NAME ".note.stapsdt" #define NOTE_STAPSDT_NAME "stapsdt" #define NOTE_STAPSDT_TYPE 3 +#define MAX_SECTION_DATA_SIZE 512 * 1024 * 1024 #if BYTE_ORDER == LITTLE_ENDIAN #define NATIVE_ELF_ENDIANNESS ELFDATA2LSB @@ -191,6 +181,7 @@ struct lttng_elf_sym { struct lttng_elf { int fd; + size_t file_size; uint8_t bitness; uint8_t endianness; /* Offset in bytes to start of section names string table. */ @@ -531,16 +522,28 @@ struct lttng_elf *lttng_elf_create(int fd) struct lttng_elf_shdr section_names_shdr; struct lttng_elf *elf = NULL; int ret; + struct stat stat_buf; if (fd < 0) { goto error; } + ret = fstat(fd, &stat_buf); + if (ret) { + PERROR("Failed to determine size of elf file"); + goto error; + } + if (!S_ISREG(stat_buf.st_mode)) { + ERR("Refusing to initialize lttng_elf from non-regular file"); + goto error; + } + elf = zmalloc(sizeof(struct lttng_elf)); if (!elf) { PERROR("Error allocating struct lttng_elf"); goto error; } + elf->file_size = (size_t) stat_buf.st_size; elf->fd = dup(fd); if (elf->fd < 0) { @@ -605,6 +608,7 @@ int lttng_elf_get_section_hdr_by_name(struct lttng_elf *elf, char *curr_section_name; for (i = 0; i < elf->ehdr->e_shnum; ++i) { + bool name_equal; int ret = lttng_elf_get_section_hdr(elf, i, section_hdr); if (ret) { @@ -615,7 +619,9 @@ int lttng_elf_get_section_hdr_by_name(struct lttng_elf *elf, if (!curr_section_name) { continue; } - if (strcmp(curr_section_name, section_name) == 0) { + name_equal = strcmp(curr_section_name, section_name) == 0; + free(curr_section_name); + if (name_equal) { return 0; } } @@ -629,17 +635,25 @@ char *lttng_elf_get_section_data(struct lttng_elf *elf, int ret; off_t section_offset; char *data; + size_t max_alloc_size; if (!elf || !shdr) { goto error; } + max_alloc_size = min_t(size_t, MAX_SECTION_DATA_SIZE, elf->file_size); + section_offset = shdr->sh_offset; if (lseek(elf->fd, section_offset, SEEK_SET) < 0) { PERROR("Error seeking to section offset"); goto error; } + if (shdr->sh_size > max_alloc_size) { + ERR("ELF section size exceeds maximal allowed size of %zu bytes", + max_alloc_size); + goto error; + } data = zmalloc(shdr->sh_size); if (!data) { PERROR("Error allocating buffer for ELF section data");