From owner-svn-src-head@freebsd.org Wed Oct 14 18:29:23 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 590EAA13579; Wed, 14 Oct 2015 18:29:23 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0A2031A6D; Wed, 14 Oct 2015 18:29:22 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t9EITM4V053297; Wed, 14 Oct 2015 18:29:22 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t9EITMmv053296; Wed, 14 Oct 2015 18:29:22 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201510141829.t9EITMmv053296@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Wed, 14 Oct 2015 18:29:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r289324 - head/libexec/rtld-elf X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 14 Oct 2015 18:29:23 -0000 Author: kib Date: Wed Oct 14 18:29:21 2015 New Revision: 289324 URL: https://svnweb.freebsd.org/changeset/base/289324 Log: Allow PT_NOTES segments to be located anywhere in the executable image. The dynamic linker still requires that program headers of the executable or dso are mapped by a PT_LOAD segment. Reviewed by: emaste, jhb Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D3871 Modified: head/libexec/rtld-elf/map_object.c Modified: head/libexec/rtld-elf/map_object.c ============================================================================== --- head/libexec/rtld-elf/map_object.c Wed Oct 14 18:29:00 2015 (r289323) +++ head/libexec/rtld-elf/map_object.c Wed Oct 14 18:29:21 2015 (r289324) @@ -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); }