Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Jan 2017 15:54:03 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r311984 - head/libexec/rtld-elf
Message-ID:  <201701121554.v0CFs3eN037304@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Jan 12 15:54:03 2017
New Revision: 311984
URL: https://svnweb.freebsd.org/changeset/base/311984

Log:
  For the main binary, postpone enforcing relro read-only protection
  until copy relocations are done.
  
  Newer binutils and lld seems to output copy into relro-protected range.
  
  Reported by: Rafael Espц╜ndola via emaste
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/libexec/rtld-elf/rtld.c

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c	Thu Jan 12 15:26:23 2017	(r311983)
+++ head/libexec/rtld-elf/rtld.c	Thu Jan 12 15:54:03 2017	(r311984)
@@ -103,6 +103,7 @@ static int load_needed_objects(Obj_Entry
 static int load_preload_objects(void);
 static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int);
 static void map_stacks_exec(RtldLockState *);
+static int obj_enforce_relro(Obj_Entry *);
 static Obj_Entry *obj_from_addr(const void *);
 static void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *);
 static void objlist_call_init(Objlist *, RtldLockState *);
@@ -617,6 +618,10 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
     if (do_copy_relocations(obj_main) == -1)
 	rtld_die();
 
+    dbg("enforcing main obj relro");
+    if (obj_enforce_relro(obj_main) == -1)
+	rtld_die();
+
     if (getenv(_LD("DUMP_REL_POST")) != NULL) {
        dump_relocations(obj_main);
        exit (0);
@@ -2746,14 +2751,8 @@ relocate_object(Obj_Entry *obj, bool bin
 	    reloc_non_plt(obj, rtldobj, flags | SYMLOOK_IFUNC, lockstate))
 		return (-1);
 
-	if (obj->relro_size > 0) {
-		if (mprotect(obj->relro_page, obj->relro_size,
-		    PROT_READ) == -1) {
-			_rtld_error("%s: Cannot enforce relro protection: %s",
-			    obj->path, rtld_strerror(errno));
-			return (-1);
-		}
-	}
+	if (!obj->mainprog && obj_enforce_relro(obj) == -1)
+		return (-1);
 
 	/*
 	 * Set up the magic number and version in the Obj_Entry.  These
@@ -5124,6 +5123,19 @@ _rtld_is_dlopened(void *arg)
 	return (res);
 }
 
+int
+obj_enforce_relro(Obj_Entry *obj)
+{
+
+	if (obj->relro_size > 0 && mprotect(obj->relro_page, obj->relro_size,
+	    PROT_READ) == -1) {
+		_rtld_error("%s: Cannot enforce relro protection: %s",
+		    obj->path, rtld_strerror(errno));
+		return (-1);
+	}
+	return (0);
+}
+
 static void
 map_stacks_exec(RtldLockState *lockstate)
 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701121554.v0CFs3eN037304>