mirror of
https://github.com/openharmony/third_party_elfutils.git
synced 2026-07-01 06:41:51 -04:00
libelf: Add ELF_E_INVALID_ELF error value.
Add ELF_E_INVALID_ELF which is set when the ELF file data is bad. This is different from ELF_E_INVALID_FILE which is set when the file could not be read. Signed-off-by: Mark Wielaard <mark@klomp.org>
This commit is contained in:
@@ -1,3 +1,15 @@
|
||||
2017-10-04 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* libelfP.h: Add ELF_E_INVALID_ELF to error values enum.
|
||||
* elf_error.c (ELF_E_INVALID_ELF_IDX): New define. Use it as value
|
||||
for ELF_E_INVALID_ELF in msgidx.
|
||||
* elf_getshdrstrndx.c (elf_getshdrstrndx): Distinquish between pread
|
||||
failing and not having enough data.
|
||||
* elf_begin.c (get_shnum): Likewise. Explicitly set libelf errno on
|
||||
too large value.
|
||||
(file_read_elf): Make sure to always set libelf errno when returning
|
||||
NULL. Distinquish between i/o file and elf data errors.
|
||||
|
||||
2017-08-18 Ulf Hermann <ulf.hermann@qt.io>
|
||||
|
||||
* gelf_xlate.c: Use attribute_packed.
|
||||
|
||||
+45
-16
@@ -158,6 +158,7 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
|
||||
else
|
||||
{
|
||||
Elf32_Word size;
|
||||
ssize_t r;
|
||||
|
||||
if (likely (map_address != NULL))
|
||||
/* gcc will optimize the memcpy to a simple memory
|
||||
@@ -167,11 +168,19 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
|
||||
+ offset))->sh_size,
|
||||
sizeof (Elf32_Word));
|
||||
else
|
||||
if (unlikely (pread_retry (fildes, &size, sizeof (Elf32_Word),
|
||||
offset + ehdr.e32->e_shoff
|
||||
+ offsetof (Elf32_Shdr, sh_size))
|
||||
if (unlikely ((r = pread_retry (fildes, &size,
|
||||
sizeof (Elf32_Word),
|
||||
offset + ehdr.e32->e_shoff
|
||||
+ offsetof (Elf32_Shdr,
|
||||
sh_size)))
|
||||
!= sizeof (Elf32_Word)))
|
||||
return (size_t) -1l;
|
||||
{
|
||||
if (r < 0)
|
||||
__libelf_seterrno (ELF_E_INVALID_FILE);
|
||||
else
|
||||
__libelf_seterrno (ELF_E_INVALID_ELF);
|
||||
return (size_t) -1l;
|
||||
}
|
||||
|
||||
if (e_ident[EI_DATA] != MY_ELFDATA)
|
||||
CONVERT (size);
|
||||
@@ -207,6 +216,7 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
|
||||
+ offset))->sh_size;
|
||||
else
|
||||
{
|
||||
ssize_t r;
|
||||
if (likely (map_address != NULL))
|
||||
/* gcc will optimize the memcpy to a simple memory
|
||||
access while taking care of alignment issues. */
|
||||
@@ -215,19 +225,30 @@ get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
|
||||
+ offset))->sh_size,
|
||||
sizeof (Elf64_Xword));
|
||||
else
|
||||
if (unlikely (pread_retry (fildes, &size, sizeof (Elf64_Xword),
|
||||
offset + ehdr.e64->e_shoff
|
||||
+ offsetof (Elf64_Shdr, sh_size))
|
||||
if (unlikely ((r = pread_retry (fildes, &size,
|
||||
sizeof (Elf64_Xword),
|
||||
offset + ehdr.e64->e_shoff
|
||||
+ offsetof (Elf64_Shdr,
|
||||
sh_size)))
|
||||
!= sizeof (Elf64_Xword)))
|
||||
return (size_t) -1l;
|
||||
{
|
||||
if (r < 0)
|
||||
__libelf_seterrno (ELF_E_INVALID_FILE);
|
||||
else
|
||||
__libelf_seterrno (ELF_E_INVALID_ELF);
|
||||
return (size_t) -1l;
|
||||
}
|
||||
|
||||
if (e_ident[EI_DATA] != MY_ELFDATA)
|
||||
CONVERT (size);
|
||||
}
|
||||
|
||||
if (size > ~((GElf_Word) 0))
|
||||
/* Invalid value, it is too large. */
|
||||
return (size_t) -1l;
|
||||
{
|
||||
/* Invalid value, it is too large. */
|
||||
__libelf_seterrno (ELF_E_INVALID_ELF);
|
||||
return (size_t) -1l;
|
||||
}
|
||||
|
||||
result = size;
|
||||
}
|
||||
@@ -255,11 +276,13 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
&& e_ident[EI_DATA] != ELFDATA2MSB)))
|
||||
{
|
||||
/* Cannot handle this. */
|
||||
__libelf_seterrno (ELF_E_INVALID_FILE);
|
||||
__libelf_seterrno (ELF_E_INVALID_ELF);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Determine the number of sections. */
|
||||
/* Determine the number of sections. Returns -1 and sets libelf errno
|
||||
if the file handle or elf file is invalid. Returns zero if there
|
||||
are no section headers (or they cannot be read). */
|
||||
size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
|
||||
if (scncnt == (size_t) -1l)
|
||||
/* Could not determine the number of sections. */
|
||||
@@ -269,10 +292,16 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
if (e_ident[EI_CLASS] == ELFCLASS32)
|
||||
{
|
||||
if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
|
||||
return NULL;
|
||||
{
|
||||
__libelf_seterrno (ELF_E_INVALID_ELF);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
|
||||
return NULL;
|
||||
{
|
||||
__libelf_seterrno (ELF_E_INVALID_ELF);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We can now allocate the memory. Even if there are no section headers,
|
||||
we allocate space for a zeroth section in case we need it later. */
|
||||
@@ -281,7 +310,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
|
||||
ELF_K_ELF, scnmax * sizeof (Elf_Scn));
|
||||
if (elf == NULL)
|
||||
/* Not enough memory. */
|
||||
/* Not enough memory. allocate_elf will have set libelf errno. */
|
||||
return NULL;
|
||||
|
||||
assert ((unsigned int) scncnt == scncnt);
|
||||
@@ -350,7 +379,7 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
|
||||
{
|
||||
free_and_out:
|
||||
free (elf);
|
||||
__libelf_seterrno (ELF_E_INVALID_FILE);
|
||||
__libelf_seterrno (ELF_E_INVALID_ELF);
|
||||
return NULL;
|
||||
}
|
||||
elf->state.elf32.shdr
|
||||
|
||||
+6
-1
@@ -94,8 +94,12 @@ static const char msgstr[] =
|
||||
(ELF_E_NOMEM_IDX + sizeof "out of memory")
|
||||
N_("invalid file descriptor")
|
||||
"\0"
|
||||
#define ELF_E_INVALID_OP_IDX \
|
||||
#define ELF_E_INVALID_ELF_IDX \
|
||||
(ELF_E_INVALID_FILE_IDX + sizeof "invalid file descriptor")
|
||||
N_("invalid ELF file data")
|
||||
"\0"
|
||||
#define ELF_E_INVALID_OP_IDX \
|
||||
(ELF_E_INVALID_ELF_IDX + sizeof "invalid ELF file data")
|
||||
N_("invalid operation")
|
||||
"\0"
|
||||
#define ELF_E_NO_VERSION_IDX \
|
||||
@@ -280,6 +284,7 @@ static const uint_fast16_t msgidx[ELF_E_NUM] =
|
||||
[ELF_E_INVALID_ENCODING] = ELF_E_INVALID_ENCODING_IDX,
|
||||
[ELF_E_NOMEM] = ELF_E_NOMEM_IDX,
|
||||
[ELF_E_INVALID_FILE] = ELF_E_INVALID_FILE_IDX,
|
||||
[ELF_E_INVALID_ELF] = ELF_E_INVALID_ELF_IDX,
|
||||
[ELF_E_INVALID_OP] = ELF_E_INVALID_OP_IDX,
|
||||
[ELF_E_NO_VERSION] = ELF_E_NO_VERSION_IDX,
|
||||
[ELF_E_INVALID_CMD] = ELF_E_INVALID_CMD_IDX,
|
||||
|
||||
@@ -133,13 +133,17 @@ elf_getshdrstrndx (Elf *elf, size_t *dst)
|
||||
/* We avoid reading in all the section headers. Just read
|
||||
the first one. */
|
||||
Elf32_Shdr shdr_mem;
|
||||
ssize_t r;
|
||||
|
||||
if (unlikely (pread_retry (elf->fildes, &shdr_mem,
|
||||
sizeof (Elf32_Shdr), offset)
|
||||
if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem,
|
||||
sizeof (Elf32_Shdr), offset))
|
||||
!= sizeof (Elf32_Shdr)))
|
||||
{
|
||||
/* We must be able to read this ELF section header. */
|
||||
__libelf_seterrno (ELF_E_INVALID_FILE);
|
||||
if (r < 0)
|
||||
__libelf_seterrno (ELF_E_INVALID_FILE);
|
||||
else
|
||||
__libelf_seterrno (ELF_E_INVALID_ELF);
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -194,13 +198,17 @@ elf_getshdrstrndx (Elf *elf, size_t *dst)
|
||||
/* We avoid reading in all the section headers. Just read
|
||||
the first one. */
|
||||
Elf64_Shdr shdr_mem;
|
||||
ssize_t r;
|
||||
|
||||
if (unlikely (pread_retry (elf->fildes, &shdr_mem,
|
||||
sizeof (Elf64_Shdr), offset)
|
||||
if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem,
|
||||
sizeof (Elf64_Shdr), offset))
|
||||
!= sizeof (Elf64_Shdr)))
|
||||
{
|
||||
/* We must be able to read this ELF section header. */
|
||||
__libelf_seterrno (ELF_E_INVALID_FILE);
|
||||
if (r < 0)
|
||||
__libelf_seterrno (ELF_E_INVALID_FILE);
|
||||
else
|
||||
__libelf_seterrno (ELF_E_INVALID_ELF);
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ enum
|
||||
ELF_E_INVALID_ENCODING,
|
||||
ELF_E_NOMEM,
|
||||
ELF_E_INVALID_FILE,
|
||||
ELF_E_INVALID_ELF,
|
||||
ELF_E_INVALID_OP,
|
||||
ELF_E_NO_VERSION,
|
||||
ELF_E_INVALID_CMD,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
2017-10-04 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* msg_tst.c: Handle ELF_E_INVALID_ELF.
|
||||
|
||||
2017-09-10 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* run-ar.sh: New test.
|
||||
|
||||
@@ -39,6 +39,7 @@ static struct
|
||||
{ ELF_E_INVALID_ENCODING, "invalid encoding" },
|
||||
{ ELF_E_NOMEM, "out of memory" },
|
||||
{ ELF_E_INVALID_FILE, "invalid file descriptor" },
|
||||
{ ELF_E_INVALID_ELF, "invalid ELF file data" },
|
||||
{ ELF_E_INVALID_OP, "invalid operation" },
|
||||
{ ELF_E_NO_VERSION, "ELF version not set" },
|
||||
{ ELF_E_INVALID_CMD, "invalid command" },
|
||||
|
||||
Reference in New Issue
Block a user