Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163395704
D26323.id76688.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D26323.id76688.diff
View Options
Index: head/libexec/rtld-elf/map_object.c
===================================================================
--- head/libexec/rtld-elf/map_object.c
+++ head/libexec/rtld-elf/map_object.c
@@ -40,11 +40,19 @@
#include "debug.h"
#include "rtld.h"
-static Elf_Ehdr *get_elf_header(int, const char *, const struct stat *);
+static Elf_Ehdr *get_elf_header(int, const char *, const struct stat *,
+ Elf_Phdr **phdr);
static int convert_flags(int); /* Elf flags -> mmap flags */
int __getosreldate(void);
+static bool
+phdr_in_zero_page(const Elf_Ehdr *hdr)
+{
+ return (hdr->e_phoff + hdr->e_phnum * sizeof(Elf_Phdr) <
+ (size_t)PAGE_SIZE);
+}
+
/*
* Map a shared object into memory. The "fd" argument is a file descriptor,
* which must be open on the object and positioned at its beginning.
@@ -95,17 +103,15 @@
size_t note_map_len;
Elf_Addr text_end;
- hdr = get_elf_header(fd, path, sb);
+ hdr = get_elf_header(fd, path, sb, &phdr);
if (hdr == NULL)
return (NULL);
/*
* Scan the program header entries, and save key information.
- *
* We expect that the loadable segments are ordered by load address.
*/
- phdr = (Elf_Phdr *)((char *)hdr + hdr->e_phoff);
- phsize = hdr->e_phnum * sizeof (phdr[0]);
+ phsize = hdr->e_phnum * sizeof(phdr[0]);
phlimit = phdr + hdr->e_phnum;
nsegs = -1;
phdyn = phinterp = phtls = NULL;
@@ -332,14 +338,18 @@
error:
if (note_map != NULL && note_map != MAP_FAILED)
munmap(note_map, note_map_len);
+ if (!phdr_in_zero_page(hdr))
+ munmap(phdr, hdr->e_phnum * sizeof(phdr[0]));
munmap(hdr, PAGE_SIZE);
return (NULL);
}
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_Ehdr *hdr;
+ Elf_Phdr *phdr;
/* Make sure file has enough data for the ELF header */
if (sbp != NULL && sbp->st_size < (off_t)sizeof(Elf_Ehdr)) {
@@ -388,11 +398,19 @@
"%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
goto error;
}
- if (hdr->e_phoff + hdr->e_phnum * sizeof(Elf_Phdr) >
- (size_t)PAGE_SIZE) {
- _rtld_error("%s: program header too large", path);
- goto error;
+ if (phdr_in_zero_page(hdr)) {
+ phdr = (Elf_Phdr *)((char *)hdr + hdr->e_phoff);
+ } else {
+ phdr = mmap(NULL, hdr->e_phnum * sizeof(phdr[0]),
+ PROT_READ, MAP_PRIVATE | MAP_PREFAULT_READ, fd,
+ hdr->e_phoff);
+ if (phdr == MAP_FAILED) {
+ _rtld_error("%s: error mapping phdr: %s", path,
+ rtld_strerror(errno));
+ goto error;
+ }
}
+ *phdr_p = phdr;
return (hdr);
error:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 23, 8:13 PM (13 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35413953
Default Alt Text
D26323.id76688.diff (2 KB)
Attached To
Mode
D26323: rtld: Handle ELF dso with program headers outside the first page.
Attached
Detach File
Event Timeline
Log In to Comment