mirror of
https://github.com/OpenAMP/open-amp.git
synced 2026-10-02 18:23:21 +08:00
remoteproc: bound ELF section name lookups
Make ELF section-name lookup validate sh_name before reading from the loaded section string table. Skip malformed section names whose sh_name offset is outside the table or whose string is not NUL-terminated within the remaining table bytes. Use bounded comparison for valid candidates so .resource_table lookup cannot read past the loaded string table. Signed-off-by: Ben Levinsky <ben.levinsky@amd.com>
This commit is contained in:
committed by
Arnaud Pouliquen
parent
08a45aca33
commit
28b0a020c6
@@ -235,6 +235,35 @@ static int *elf_load_state(void *elf_info)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compare a section name with a bounded section string table entry.
|
||||
*
|
||||
* @param name Section name to match.
|
||||
* @param name_table Loaded section string table.
|
||||
* @param name_table_size Size of the loaded section string table.
|
||||
* @param sh_name Offset of the candidate name in the string table.
|
||||
*
|
||||
* @return true if the name matches, otherwise false.
|
||||
*/
|
||||
static bool elf_section_name_matches(const char *name, const char *name_table,
|
||||
size_t name_table_size, size_t sh_name)
|
||||
{
|
||||
size_t name_len;
|
||||
size_t remaining;
|
||||
const char *candidate;
|
||||
|
||||
if (sh_name >= name_table_size)
|
||||
return false;
|
||||
|
||||
remaining = name_table_size - sh_name;
|
||||
name_len = strlen(name);
|
||||
if (name_len >= remaining)
|
||||
return false;
|
||||
|
||||
candidate = name_table + sh_name;
|
||||
return memcmp(name, candidate, name_len + 1) == 0;
|
||||
}
|
||||
|
||||
static void elf_parse_segment(void *elf_info, const void *elf_phdr,
|
||||
unsigned int *p_type, size_t *p_offset,
|
||||
metal_phys_addr_t *p_vaddr,
|
||||
@@ -303,6 +332,7 @@ static void *elf_get_section_from_name(void *elf_info, const char *name)
|
||||
{
|
||||
unsigned int i;
|
||||
const char *name_table;
|
||||
size_t name_table_size;
|
||||
|
||||
if (elf_is_64(elf_info) == 0) {
|
||||
struct elf32_info *einfo = elf_info;
|
||||
@@ -310,10 +340,13 @@ static void *elf_get_section_from_name(void *elf_info, const char *name)
|
||||
Elf32_Shdr *shdr = einfo->shdrs;
|
||||
|
||||
name_table = einfo->shstrtab;
|
||||
name_table_size = einfo->shstrtab_size;
|
||||
if (!shdr || !name_table)
|
||||
return NULL;
|
||||
for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
|
||||
if (strcmp(name, name_table + shdr->sh_name))
|
||||
if (!elf_section_name_matches(name, name_table,
|
||||
name_table_size,
|
||||
shdr->sh_name))
|
||||
continue;
|
||||
else
|
||||
return shdr;
|
||||
@@ -324,10 +357,13 @@ static void *elf_get_section_from_name(void *elf_info, const char *name)
|
||||
Elf64_Shdr *shdr = einfo->shdrs;
|
||||
|
||||
name_table = einfo->shstrtab;
|
||||
name_table_size = einfo->shstrtab_size;
|
||||
if (!shdr || !name_table)
|
||||
return NULL;
|
||||
for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
|
||||
if (strcmp(name, name_table + shdr->sh_name))
|
||||
if (!elf_section_name_matches(name, name_table,
|
||||
name_table_size,
|
||||
shdr->sh_name))
|
||||
continue;
|
||||
else
|
||||
return shdr;
|
||||
|
||||
Reference in New Issue
Block a user