示例#1
0
int64_t
private_check_segments(struct bfelf_file_t *ef)
{
    bfelf64_xword i = 0;

    for (i = 0; i < ef->ehdr->e_phnum; i++)
    {
        struct bfelf_phdr *phdr = private_get_segment(ef, i);

        if (phdr->p_type != bfpt_load)
            continue;

        if (ef->num_loadable_segments >= BFELF_MAX_SEGMENTS)
            return loader_full("increase BFELF_MAX_SEGMENTS");

        if (phdr->p_memsz < phdr->p_filesz)
            return invalid_segment("segment mem size is less then file size");

        if (phdr->p_vaddr != phdr->p_paddr)
            return invalid_segment("expect p_vaddr == p_paddr");

        if (phdr->p_align != 0x1000 && phdr->p_align != 0x200000)
            return invalid_segment("expect 4k or 2M alignment");

        if (phdr->p_offset >= ef->fsize)
            return invalid_segment("segment offset out of bounds");

        ef->loadable_segments[ef->num_loadable_segments] = phdr;
        ef->num_loadable_segments++;
    }

    return BFELF_SUCCESS;
}
示例#2
0
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;
}
示例#3
0
static bfelf64_sword
private_check_segments(struct bfelf_file_t *ef)
{
    bfelf64_sword i = 0;

    for (i = 0; i < ef->ehdr->e_phnum; i++)
    {
        struct bfelf_phdr *phdr = private_get_segment(ef, i);

        if (phdr->p_type != bfpt_load)
            continue;

        if (ef->num_loadable_segments >= BFELF_MAX_SEGMENTS)
            return loader_full("increase BFELF_MAX_SEGMENTS");

        if (phdr->p_memsz < phdr->p_filesz)
            return invalid_segment("segment mem size is less then file size");

        if (phdr->p_vaddr != phdr->p_paddr)
            return invalid_segment("expect p_vaddr == p_paddr");

        /*
         * At the moment, libc++.so has an alignment of 20, which is really
         * strange. Will need to find out why at some point
         *
         * if (phdr->p_align != 0x1000 && phdr->p_align != 0x200000)
         *     return invalid_segment("expect 4k or 2M alignment");
         */

        if (phdr->p_offset >= ef->fsize)
            return invalid_segment("segment offset out of bounds");

        ef->loadable_segments[ef->num_loadable_segments] = phdr;
        ef->num_loadable_segments++;
    }

    return BFELF_SUCCESS;
}
示例#4
0
static bfelf64_sword
private_check_entry(struct bfelf_file_t *ef)
{
    bfelf64_sword i = 0;
    bfelf64_sword valid_addr = 0;

    for (i = 0; i < ef->ehdr->e_phnum; i++)
    {
        struct bfelf_phdr *phdr = private_get_segment(ef, i);

        if (ef->ehdr->e_entry >= phdr->p_vaddr &&
            ef->ehdr->e_entry < phdr->p_vaddr + phdr->p_memsz)
        {
            valid_addr = 1;
            break;
        }
    }

    if (ef->ehdr->e_entry != 0 && valid_addr == 0)
        return invalid_file("ELF entry corrupt");

    return BFELF_SUCCESS;
}