aboutsummaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authorMaxim Sobolev <sobomax@FreeBSD.org>2016-01-30 04:16:05 +0000
committerMaxim Sobolev <sobomax@FreeBSD.org>2016-01-30 04:16:05 +0000
commit7fd852f860b047f0e540360760aa4c95fd9285b2 (patch)
tree2ef9e831fbd7f5fc5c71114fc48675cc255240ca /libexec
parent5842bd683f574d0fa8d2f408b4f29d4bb4beba95 (diff)
downloadsrc-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.c12
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) {