rtld: extract header validation into new helper check_elf_headers()
Reviewed by: emaste Discussed with: jrtc27 Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D32960
This commit is contained in:
parent
01c77a436e
commit
63fc4e820c
@ -345,6 +345,39 @@ map_object(int fd, const char *path, const struct stat *sb)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
check_elf_headers(const Elf_Ehdr *hdr, const char *path)
|
||||||
|
{
|
||||||
|
if (!IS_ELF(*hdr)) {
|
||||||
|
_rtld_error("%s: invalid file format", path);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
|
||||||
|
hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
|
||||||
|
_rtld_error("%s: unsupported file layout", path);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
if (hdr->e_ident[EI_VERSION] != EV_CURRENT ||
|
||||||
|
hdr->e_version != EV_CURRENT) {
|
||||||
|
_rtld_error("%s: unsupported file version", path);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
|
||||||
|
_rtld_error("%s: unsupported file type", path);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
if (hdr->e_machine != ELF_TARG_MACH) {
|
||||||
|
_rtld_error("%s: unsupported machine", path);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
if (hdr->e_phentsize != sizeof(Elf_Phdr)) {
|
||||||
|
_rtld_error(
|
||||||
|
"%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
static Elf_Ehdr *
|
static Elf_Ehdr *
|
||||||
get_elf_header(int fd, const char *path, const struct stat *sbp,
|
get_elf_header(int fd, const char *path, const struct stat *sbp,
|
||||||
Elf_Phdr **phdr_p)
|
Elf_Phdr **phdr_p)
|
||||||
@ -366,39 +399,14 @@ get_elf_header(int fd, const char *path, const struct stat *sbp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the file is valid */
|
/* Make sure the file is valid */
|
||||||
if (!IS_ELF(*hdr)) {
|
if (!check_elf_headers(hdr, path))
|
||||||
_rtld_error("%s: invalid file format", path);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
|
|
||||||
hdr->e_ident[EI_DATA] != ELF_TARG_DATA) {
|
|
||||||
_rtld_error("%s: unsupported file layout", path);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (hdr->e_ident[EI_VERSION] != EV_CURRENT ||
|
|
||||||
hdr->e_version != EV_CURRENT) {
|
|
||||||
_rtld_error("%s: unsupported file version", path);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN) {
|
|
||||||
_rtld_error("%s: unsupported file type", path);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (hdr->e_machine != ELF_TARG_MACH) {
|
|
||||||
_rtld_error("%s: unsupported machine", path);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We rely on the program header being in the first page. This is
|
* We rely on the program header being in the first page. This is
|
||||||
* not strictly required by the ABI specification, but it seems to
|
* not strictly required by the ABI specification, but it seems to
|
||||||
* always true in practice. And, it simplifies things considerably.
|
* always true in practice. And, it simplifies things considerably.
|
||||||
*/
|
*/
|
||||||
if (hdr->e_phentsize != sizeof(Elf_Phdr)) {
|
|
||||||
_rtld_error(
|
|
||||||
"%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
if (phdr_in_zero_page(hdr)) {
|
if (phdr_in_zero_page(hdr)) {
|
||||||
phdr = (Elf_Phdr *)((char *)hdr + hdr->e_phoff);
|
phdr = (Elf_Phdr *)((char *)hdr + hdr->e_phoff);
|
||||||
} else {
|
} else {
|
||||||
|
@ -405,6 +405,7 @@ void free_tls_offset(Obj_Entry *obj);
|
|||||||
const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long);
|
const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long);
|
||||||
int convert_prot(int elfflags);
|
int convert_prot(int elfflags);
|
||||||
void *_get_tp(void); /* libc implementation */
|
void *_get_tp(void); /* libc implementation */
|
||||||
|
bool check_elf_headers(const Elf_Ehdr *hdr, const char *path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MD function declarations.
|
* MD function declarations.
|
||||||
|
Loading…
Reference in New Issue
Block a user