/*
- * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
- * Copyright (C) 2017 Francis Deslauriers <francis.deslauriers@efficios.com>
- * Copyright (C) 2017 Erica Bugden <erica.bugden@efficios.com>
+ * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+ * Copyright (C) 2017 Francis Deslauriers <francis.deslauriers@efficios.com>
+ * Copyright (C) 2017 Erica Bugden <erica.bugden@efficios.com>
*
- * 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 <common/compat/endian.h>
#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
dst_sym.st_size = src_sym.st_size; \
} while (0)
-/* Both 32bit and 64bit use the same 1 byte field for type. (See elf.h) */
-#define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
+#ifndef ELFCLASSNUM
+#define ELFCLASSNUM 3
+#endif
+
+#ifndef ELFDATANUM
+#define ELFDATANUM 3
+#endif
+
+#ifndef EV_NUM
+#define EV_NUM 2
+#endif
struct lttng_elf_ehdr {
uint16_t e_type;
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. */
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) {
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");
char *curr_sym_str = NULL;
char *symbol_table_data = NULL;
char *string_table_data = NULL;
- char *string_table_name = NULL;
+ const char *string_table_name = NULL;
struct lttng_elf_shdr symtab_hdr;
struct lttng_elf_shdr strtab_hdr;
struct lttng_elf *elf = NULL;
/*
* If the current symbol is not a function; skip to the next symbol.
*/
- if (ELF_ST_TYPE(curr_sym.st_info) != STT_FUNC) {
+ /* Both 32bit and 64bit use the same 1 byte field for type. (See elf.h) */
+ if (ELF32_ST_TYPE(curr_sym.st_info) != STT_FUNC) {
continue;
}