diff options
author | Maxim Sobolev <sobomax@FreeBSD.org> | 2016-01-30 04:16:05 +0000 |
---|---|---|
committer | Maxim Sobolev <sobomax@FreeBSD.org> | 2016-01-30 04:16:05 +0000 |
commit | 7fd852f860b047f0e540360760aa4c95fd9285b2 (patch) | |
tree | 2ef9e831fbd7f5fc5c71114fc48675cc255240ca /libexec | |
parent | 5842bd683f574d0fa8d2f408b4f29d4bb4beba95 (diff) | |
download | src-7fd852f860b047f0e540360760aa4c95fd9285b2.tar.gz src-7fd852f860b047f0e540360760aa4c95fd9285b2.zip |
This seems like a very trivial bug that should have been squashed a long
time ago, but for some reason it was not. Basically, without this change
dlopen(3)'ing an empty .so file would just cause application to dump core
with SIGSEGV.
Make sure the file has enough data for at least the ELF header before
mmap'ing it.
Add a test case to check that dlopen an empty file return an error.
There were a separate discussion as to whether it should be SIGBUS
instead when you try to access region mapped from an empty file,
but it's definitely SIGSEGV now, so if anyone want to check that please
be my guest.
Reviewed by: mjg, cem
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D5112
Notes
Notes:
svn path=/head/; revision=295059
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rtld-elf/map_object.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index 6012015bcc28..f4f6f4221816 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -38,7 +38,7 @@ #include "debug.h" #include "rtld.h" -static Elf_Ehdr *get_elf_header(int, const char *); +static Elf_Ehdr *get_elf_header(int, const char *, const struct stat *); static int convert_prot(int); /* Elf flags -> mmap protection */ static int convert_flags(int); /* Elf flags -> mmap flags */ @@ -91,7 +91,7 @@ map_object(int fd, const char *path, const struct stat *sb) char *note_map; size_t note_map_len; - hdr = get_elf_header(fd, path); + hdr = get_elf_header(fd, path, sb); if (hdr == NULL) return (NULL); @@ -324,10 +324,16 @@ error: } static Elf_Ehdr * -get_elf_header(int fd, const char *path) +get_elf_header(int fd, const char *path, const struct stat *sbp) { Elf_Ehdr *hdr; + /* Make sure file has enough data for the ELF header */ + if (sbp != NULL && sbp->st_size < sizeof(Elf_Ehdr)) { + _rtld_error("%s: invalid file format", path); + return (NULL); + } + hdr = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE | MAP_PREFAULT_READ, fd, 0); if (hdr == (Elf_Ehdr *)MAP_FAILED) { |