Date: Wed, 28 Oct 2015 11:32:39 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r290099 - stable/10/libexec/rtld-elf Message-ID: <201510281132.t9SBWdPw033904@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Wed Oct 28 11:32:39 2015 New Revision: 290099 URL: https://svnweb.freebsd.org/changeset/base/290099 Log: MFC r289324: Allow PT_NOTES segments to be located anywhere in the executable image. Modified: stable/10/libexec/rtld-elf/map_object.c Directory Properties: stable/10/ (props changed) Modified: stable/10/libexec/rtld-elf/map_object.c ============================================================================== --- stable/10/libexec/rtld-elf/map_object.c Wed Oct 28 11:29:58 2015 (r290098) +++ stable/10/libexec/rtld-elf/map_object.c Wed Oct 28 11:32:39 2015 (r290099) @@ -88,6 +88,8 @@ map_object(int fd, const char *path, con 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 @@ map_object(int fd, const char *path, con 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 @@ map_object(int fd, const char *path, con 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 == MAP_FAILED) { + _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 @@ map_object(int fd, const char *path, con 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 != MAP_FAILED) + munmap(note_map, note_map_len); munmap(hdr, PAGE_SIZE); return (NULL); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510281132.t9SBWdPw033904>