Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F132151237
D3871.id9332.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D3871.id9332.diff
View Options
Index: libexec/rtld-elf/map_object.c
===================================================================
--- libexec/rtld-elf/map_object.c
+++ libexec/rtld-elf/map_object.c
@@ -88,6 +88,8 @@
size_t relro_size;
Elf_Addr note_start;
Elf_Addr note_end;
+ char *note_map;
+ size_t note_map_len;
hdr = get_elf_header(fd, path);
if (hdr == NULL)
@@ -108,6 +110,7 @@
relro_size = 0;
note_start = 0;
note_end = 0;
+ note_map = NULL;
segs = alloca(sizeof(segs[0]) * hdr->e_phnum);
stack_flags = RTLD_DEFAULT_STACK_PF_EXEC | PF_R | PF_W;
while (phdr < phlimit) {
@@ -150,9 +153,20 @@
case PT_NOTE:
if (phdr->p_offset > PAGE_SIZE ||
- phdr->p_offset + phdr->p_filesz > PAGE_SIZE)
- break;
- note_start = (Elf_Addr)(char *)hdr + phdr->p_offset;
+ phdr->p_offset + phdr->p_filesz > PAGE_SIZE) {
+ note_map_len = round_page(phdr->p_offset +
+ phdr->p_filesz) - trunc_page(phdr->p_offset);
+ note_map = mmap(NULL, note_map_len, PROT_READ,
+ MAP_PRIVATE, fd, trunc_page(phdr->p_offset));
+ if (note_map == (char *)-1) {
+ _rtld_error("%s: error mapping PT_NOTE (%d)", path, errno);
+ goto error;
+ }
+ note_start = (Elf_Addr)(note_map + phdr->p_offset -
+ trunc_page(phdr->p_offset));
+ } else {
+ note_start = (Elf_Addr)(char *)hdr + phdr->p_offset;
+ }
note_end = note_start + phdr->p_filesz;
break;
}
@@ -295,12 +309,16 @@
obj->relro_size = round_page(relro_size);
if (note_start < note_end)
digest_notes(obj, note_start, note_end);
+ if (note_map != NULL)
+ munmap(note_map, note_map_len);
munmap(hdr, PAGE_SIZE);
return (obj);
error1:
munmap(mapbase, mapsize);
error:
+ if (note_map != NULL && note_map != (char *)-1)
+ munmap(note_map, note_map_len);
munmap(hdr, PAGE_SIZE);
return (NULL);
}
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -721,21 +721,22 @@
static int
__CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
{
- const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
+ struct thread *td;
+ const Elf_Ehdr *hdr;
const Elf_Phdr *phdr;
Elf_Auxargs *elf_auxargs;
struct vmspace *vmspace;
- vm_prot_t prot;
- u_long text_size = 0, data_size = 0, total_size = 0;
- u_long text_addr = 0, data_addr = 0;
- u_long seg_size, seg_addr;
- u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0;
- int32_t osrel = 0;
- int error = 0, i, n, interp_name_len = 0;
- const char *err_str = NULL, *interp = NULL, *newinterp = NULL;
+ const char *err_str, *newinterp;
+ char *interp, *interp_buf, *path;
Elf_Brandinfo *brand_info;
- char *path;
struct sysentvec *sv;
+ vm_prot_t prot;
+ u_long text_size, data_size, total_size, text_addr, data_addr;
+ u_long seg_size, seg_addr, addr, baddr, et_dyn_addr, entry, proghdr;
+ int32_t osrel;
+ int error, i, n, interp_name_len, have_interp;
+
+ hdr = (const Elf_Ehdr *)imgp->image_header;
/*
* Do we have a valid ELF header ?
@@ -763,8 +764,17 @@
uprintf("Unaligned program headers\n");
return (ENOEXEC);
}
- n = 0;
+
+ n = error = 0;
baddr = 0;
+ osrel = 0;
+ text_size = data_size = total_size = text_addr = data_addr = 0;
+ entry = proghdr = 0;
+ interp_name_len = 0;
+ err_str = newinterp = NULL;
+ interp = interp_buf = NULL;
+ td = curthread;
+
for (i = 0; i < hdr->e_phnum; i++) {
switch (phdr[i].p_type) {
case PT_LOAD:
@@ -774,14 +784,32 @@
break;
case PT_INTERP:
/* Path to interpreter */
- if (phdr[i].p_filesz > MAXPATHLEN ||
- phdr[i].p_offset > PAGE_SIZE ||
- phdr[i].p_filesz > PAGE_SIZE - phdr[i].p_offset) {
+ if (phdr[i].p_filesz > MAXPATHLEN) {
uprintf("Invalid PT_INTERP\n");
- return (ENOEXEC);
+ error = ENOEXEC;
+ goto ret;
}
- interp = imgp->image_header + phdr[i].p_offset;
interp_name_len = phdr[i].p_filesz;
+ if (phdr[i].p_offset > PAGE_SIZE ||
+ interp_name_len > PAGE_SIZE - phdr[i].p_offset) {
+ VOP_UNLOCK(imgp->vp, 0);
+ interp_buf = malloc(interp_name_len + 1, M_TEMP,
+ M_WAITOK);
+ vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
+ error = vn_rdwr(UIO_READ, imgp->vp, interp_buf,
+ interp_name_len, phdr[i].p_offset,
+ UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
+ NOCRED, NULL, td);
+ if (error != 0) {
+ uprintf("i/o error PT_INTERP\n");
+ goto ret;
+ }
+ interp_buf[interp_name_len] = '\0';
+ interp = interp_buf;
+ } else {
+ interp = __DECONST(char *, imgp->image_header) +
+ phdr[i].p_offset;
+ }
break;
case PT_GNU_STACK:
if (__elfN(nxstack))
@@ -797,12 +825,14 @@
if (brand_info == NULL) {
uprintf("ELF binary type \"%u\" not known.\n",
hdr->e_ident[EI_OSABI]);
- return (ENOEXEC);
+ error = ENOEXEC;
+ goto ret;
}
if (hdr->e_type == ET_DYN) {
if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) {
uprintf("Cannot execute shared object\n");
- return (ENOEXEC);
+ error = ENOEXEC;
+ goto ret;
}
/*
* Honour the base load address from the dso if it is
@@ -835,8 +865,8 @@
imgp->proc->p_sysent = sv;
vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
- if (error)
- return (error);
+ if (error != 0)
+ goto ret;
for (i = 0; i < hdr->e_phnum; i++) {
switch (phdr[i].p_type) {
@@ -849,7 +879,7 @@
phdr[i].p_memsz, phdr[i].p_filesz, prot,
sv->sv_pagesize);
if (error != 0)
- return (error);
+ goto ret;
/*
* If this segment contains the program headers,
@@ -921,7 +951,8 @@
if (err_str != NULL) {
PROC_UNLOCK(imgp->proc);
uprintf("%s\n", err_str);
- return (ENOMEM);
+ error = ENOMEM;
+ goto ret;
}
vmspace = imgp->proc->p_vmspace;
@@ -936,14 +967,14 @@
* calculation is that it leaves room for the heap to grow to
* its maximum allowed size.
*/
- addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(curthread,
+ addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(td,
RLIMIT_DATA));
PROC_UNLOCK(imgp->proc);
imgp->entry_addr = entry;
if (interp != NULL) {
- int have_interp = FALSE;
+ have_interp = FALSE;
VOP_UNLOCK(imgp->vp, 0);
if (brand_info->emul_path != NULL &&
brand_info->emul_path[0] != '\0') {
@@ -969,7 +1000,7 @@
vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
if (error != 0) {
uprintf("ELF interpreter %s not found\n", interp);
- return (error);
+ goto ret;
}
} else
addr = et_dyn_addr;
@@ -993,6 +1024,8 @@
imgp->reloc_base = addr;
imgp->proc->p_osrel = osrel;
+ ret:
+ free(interp_buf, M_TEMP);
return (error);
}
@@ -2122,19 +2155,41 @@
{
const Elf_Note *note, *note0, *note_end;
const char *note_name;
- int i;
+ char *buf;
+ int i, error;
+ boolean_t res;
- if (pnote == NULL || pnote->p_offset > PAGE_SIZE ||
- pnote->p_filesz > PAGE_SIZE - pnote->p_offset)
+ if (pnote == NULL || pnote->p_filesz > PAGE_SIZE)
return (FALSE);
-
- note = note0 = (const Elf_Note *)(imgp->image_header + pnote->p_offset);
- note_end = (const Elf_Note *)(imgp->image_header +
- pnote->p_offset + pnote->p_filesz);
+ ASSERT_VOP_LOCKED(imgp->vp, "parse_notes");
+ if (pnote->p_offset > PAGE_SIZE ||
+ pnote->p_filesz > PAGE_SIZE - pnote->p_offset) {
+ VOP_UNLOCK(imgp->vp, 0);
+ buf = malloc(pnote->p_filesz, M_TEMP, M_WAITOK);
+ vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
+ error = vn_rdwr(UIO_READ, imgp->vp, buf, pnote->p_filesz,
+ pnote->p_offset, UIO_SYSSPACE, IO_NODELOCKED,
+ curthread->td_ucred, NOCRED, NULL, curthread);
+ if (error != 0) {
+ uprintf("i/o error PT_NOTE\n");
+ res = FALSE;
+ goto ret;
+ }
+ note = note0 = (const Elf_Note *)buf;
+ note_end = (const Elf_Note *)(buf + pnote->p_filesz);
+ } else {
+ note = note0 = (const Elf_Note *)(imgp->image_header +
+ pnote->p_offset);
+ note_end = (const Elf_Note *)(imgp->image_header +
+ pnote->p_offset + pnote->p_filesz);
+ buf = NULL;
+ }
for (i = 0; i < 100 && note >= note0 && note < note_end; i++) {
if (!aligned(note, Elf32_Addr) || (const char *)note_end -
- (const char *)note < sizeof(Elf_Note))
- return (FALSE);
+ (const char *)note < sizeof(Elf_Note)) {
+ res = FALSE;
+ goto ret;
+ }
if (note->n_namesz != checknote->hdr.n_namesz ||
note->n_descsz != checknote->hdr.n_descsz ||
note->n_type != checknote->hdr.n_type)
@@ -2150,17 +2205,21 @@
* from the ELF OSABI-note if necessary.
*/
if ((checknote->flags & BN_TRANSLATE_OSREL) != 0 &&
- checknote->trans_osrel != NULL)
- return (checknote->trans_osrel(note, osrel));
- return (TRUE);
-
+ checknote->trans_osrel != NULL) {
+ res = checknote->trans_osrel(note, osrel);
+ goto ret;
+ }
+ res = TRUE;
+ goto ret;
nextnote:
note = (const Elf_Note *)((const char *)(note + 1) +
roundup2(note->n_namesz, ELF_NOTE_ROUNDSIZE) +
roundup2(note->n_descsz, ELF_NOTE_ROUNDSIZE));
}
-
- return (FALSE);
+ res = FALSE;
+ret:
+ free(buf, M_TEMP);
+ return (res);
}
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Oct 15, 5:42 AM (17 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23744596
Default Alt Text
D3871.id9332.diff (8 KB)
Attached To
Mode
D3871: Allow to fetch interpreter and notes from other places of the executable file
Attached
Detach File
Event Timeline
Log In to Comment