int64_t private_check_section(struct bfelf_shdr *shdr, bfelf64_word type, bfelf64_xword flags, bfelf64_xword addralign, bfelf64_xword entsize) { /* * All of the section types that we support exist in the lower 8 bits. * The exception to that is SHT_X86_64_UNWIND which is a processor * specific type for SHT_PROGBITS defined in the 64bit System V ABI. * Since we look for SHT_PROGBITS when we see SHT_X86_64_UNWIND, the below * mask fixes the issue. */ if ((shdr->sh_type & 0xFF) != type) return invalid_section("type mismatch"); if ((shdr->sh_flags & ~flags) != 0) return invalid_section("flags mismatch"); if (shdr->sh_addralign != addralign) return invalid_section("address alignment mismatch"); if (shdr->sh_entsize != 0 && shdr->sh_entsize != entsize) return invalid_section("entry size mismatch"); return BFELF_SUCCESS; }
static bfelf64_sword private_check_sections(struct bfelf_file_t *ef) { bfelf64_sword i = 0; bfelf64_sword j = 0; struct bfelf_shdr *shstrtab = private_get_section(ef, ef->ehdr->e_shstrndx); for (i = 0; i < ef->ehdr->e_shnum; i++) { bfelf64_sword valid_addr = 0; struct bfelf_shdr *shdr = private_get_section(ef, i); if (shdr->sh_type != bfsht_nobits) { if (shdr->sh_offset + shdr->sh_size > ef->fsize) return invalid_section("section offset / size is corrupt"); } if (shdr->sh_name >= shstrtab->sh_size) return invalid_section("invalid section name offset"); if (shdr->sh_link >= ef->ehdr->e_shnum) return invalid_section("invalid section link"); for (j = 0; j < ef->ehdr->e_phnum; j++) { struct bfelf_phdr *phdr = private_get_segment(ef, j); if (shdr->sh_addr >= phdr->p_vaddr && shdr->sh_addr + shdr->sh_size <= phdr->p_vaddr + phdr->p_memsz) { valid_addr = 1; break; } } if (shdr->sh_addr != 0 && valid_addr == 0) return invalid_section("section address is out of bounds"); } return BFELF_SUCCESS; }
static bfelf64_sword private_check_section(struct bfelf_shdr *shdr, bfelf64_word type, bfelf64_xword flags, bfelf64_xword addralign, bfelf64_xword entsize) { if (shdr->sh_type != type) return invalid_section("type mismatch"); if ((shdr->sh_flags & ~flags) != 0) return invalid_section("flags mismatch"); if (shdr->sh_addralign != addralign) return invalid_section("address alignment mismatch"); if (shdr->sh_entsize != entsize) return invalid_section("entry size mismatch"); return BFELF_SUCCESS; }
static bfelf64_sword private_get_hash_table(struct bfelf_file_t *ef) { if (ef->hashtab) { bfelf64_word total = 0; bfelf64_word *p = (bfelf64_word *)(ef->hashtab->sh_offset + ef->file); if (sizeof(bfelf64_word) * 2 > ef->hashtab->sh_size) return invalid_section("hash table contents corrupt"); ef->nbucket = p[0]; ef->nchain = p[1]; total = (ef->nbucket + ef->nchain + 2) * sizeof(bfelf64_word); if (total > ef->hashtab->sh_size) return invalid_section("hash table contents corrupt"); ef->bucket = &(p[2]); ef->chain = &(p[2 + ef->nbucket]); } return BFELF_SUCCESS; }