Sync lttng-modules ABI version in internal kernel-ioctl.h
[lttng-tools.git] / src / common / lttng-elf.c
index b2aa88487e1dff286c21d0442f6cdf175a68681f..63e658177c67f9aee422830d055c9b7987544a1e 100644 (file)
@@ -43,6 +43,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 +192,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 +533,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 +619,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 +630,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 +646,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");
This page took 0.025504 seconds and 5 git commands to generate.