Module Name:    src
Committed By:   christos
Date:           Sat Apr 18 17:44:53 UTC 2020

Modified Files:
        src/tests/lib/libc/sys: Makefile t_mprotect.c
Added Files:
        src/tests/lib/libc/sys: t_mprotect_helper.c

Log Message:
PR/55177: Carlo Arenas: mremap(MAP_REMAPDUP) fails after fork()


To generate a diff of this commit:
cvs rdiff -u -r1.61 -r1.62 src/tests/lib/libc/sys/Makefile
cvs rdiff -u -r1.8 -r1.9 src/tests/lib/libc/sys/t_mprotect.c
cvs rdiff -u -r0 -r1.1 src/tests/lib/libc/sys/t_mprotect_helper.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/lib/libc/sys/Makefile
diff -u src/tests/lib/libc/sys/Makefile:1.61 src/tests/lib/libc/sys/Makefile:1.62
--- src/tests/lib/libc/sys/Makefile:1.61	Fri Mar  6 13:32:35 2020
+++ src/tests/lib/libc/sys/Makefile	Sat Apr 18 13:44:53 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.61 2020/03/06 18:32:35 kamil Exp $
+# $NetBSD: Makefile,v 1.62 2020/04/18 17:44:53 christos Exp $
 
 MKMAN=	no
 
@@ -85,7 +85,7 @@ TESTS_C+=		t_wait_noproc
 TESTS_C+=		t_wait_noproc_wnohang
 TESTS_C+=		t_write
 
-SRCS.t_mprotect=	t_mprotect.c ${SRCS_EXEC_PROT}
+SRCS.t_mprotect=	t_mprotect.c ${SRCS_EXEC_PROT} t_mprotect_helper.c
 
 LDADD.t_getpid+=        -lpthread
 

Index: src/tests/lib/libc/sys/t_mprotect.c
diff -u src/tests/lib/libc/sys/t_mprotect.c:1.8 src/tests/lib/libc/sys/t_mprotect.c:1.9
--- src/tests/lib/libc/sys/t_mprotect.c:1.8	Tue Jul 16 13:29:18 2019
+++ src/tests/lib/libc/sys/t_mprotect.c	Sat Apr 18 13:44:53 2020
@@ -1,7 +1,7 @@
-/* $NetBSD: t_mprotect.c,v 1.8 2019/07/16 17:29:18 martin Exp $ */
+/* $NetBSD: t_mprotect.c,v 1.9 2020/04/18 17:44:53 christos Exp $ */
 
 /*-
- * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * Copyright (c) 2011, 2020 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_mprotect.c,v 1.8 2019/07/16 17:29:18 martin Exp $");
+__RCSID("$NetBSD: t_mprotect.c,v 1.9 2020/04/18 17:44:53 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/mman.h>
@@ -45,6 +45,7 @@ __RCSID("$NetBSD: t_mprotect.c,v 1.8 201
 #include <atf-c.h>
 
 #include "../common/exec_prot.h"
+#include "t_mprotect_helper.h"
 
 static long	page = 0;
 static char	path[] = "mmap";
@@ -243,8 +244,8 @@ ATF_TC_BODY(mprotect_pax, tc)
 	 *   (3) making a non-executable mapping executable
 	 *
 	 *   (4) making an executable/read-only file mapping
-	 *       writable except for performing relocations
-	 *       on an ET_DYN ELF file (non-PIC shared library)
+	 *	 writable except for performing relocations
+	 *	 on an ET_DYN ELF file (non-PIC shared library)
 	 *
 	 *  The following will test only the case (3).
 	 *
@@ -383,6 +384,60 @@ ATF_TC_BODY(mprotect_mremap_exec, tc)
 	ATF_REQUIRE(munmap(map2, page) == 0);
 }
 
+ATF_TC(mprotect_mremap_fork_exec);
+ATF_TC_HEAD(mprotect_mremap_fork_exec, tc)
+{
+       atf_tc_set_md_var(tc, "descr",
+	   "Test mremap(2)+fork(2)+mprotect(2) executable space protections");
+}
+
+ATF_TC_BODY(mprotect_mremap_fork_exec, tc)
+{
+	void *map, *map2;
+	pid_t pid;
+
+	atf_tc_expect_fail("PR lib/55177");
+
+	/*
+	 * Map a page read/write/exec and duplicate it.
+	 * Map the copy executable.
+	 * Copy a function to the writeable mapping and execute it
+	 * Fork a child and wait for it
+	 * Copy a different function to the writeable mapping and execute it
+	 * The original function shouldn't be called
+	 */
+
+	map = mmap(NULL, page, PROT_READ|PROT_WRITE|PROT_MPROTECT(PROT_EXEC),
+	    MAP_ANON, -1, 0);
+	ATF_REQUIRE(map != MAP_FAILED);
+	map2 = mremap(map, page, NULL, page, MAP_REMAPDUP);
+	ATF_REQUIRE(map2 != MAP_FAILED);
+	ATF_REQUIRE(mprotect(map2, page, PROT_EXEC|PROT_READ) == 0);
+
+	memcpy(map, (void *)return_1,
+	    (uintptr_t)return_2 - (uintptr_t)return_1);
+	__builtin___clear_cache(map, (void *)((uintptr_t)map + page));
+
+	ATF_REQUIRE(((int (*)(void))map2)() == 1);
+
+	pid = fork();
+	ATF_REQUIRE(pid >= 0);
+
+	if (pid == 0)
+		_exit(0);
+
+	(void)wait(NULL);
+
+	memcpy(map, (void *)return_2,
+	    (uintptr_t)return_3 - (uintptr_t)return_2);
+	__builtin___clear_cache(map, (void *)((uintptr_t)map + page));
+
+	ATF_REQUIRE(((int (*)(void))map2)() == 2);
+
+	ATF_REQUIRE(munmap(map, page) == 0);
+	ATF_REQUIRE(munmap(map2, page) == 0);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 	page = sysconf(_SC_PAGESIZE);
@@ -394,6 +449,7 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, mprotect_pax);
 	ATF_TP_ADD_TC(tp, mprotect_write);
 	ATF_TP_ADD_TC(tp, mprotect_mremap_exec);
+	ATF_TP_ADD_TC(tp, mprotect_mremap_fork_exec);
 
 	return atf_no_error();
 }

Added files:

Index: src/tests/lib/libc/sys/t_mprotect_helper.c
diff -u /dev/null src/tests/lib/libc/sys/t_mprotect_helper.c:1.1
--- /dev/null	Sat Apr 18 13:44:53 2020
+++ src/tests/lib/libc/sys/t_mprotect_helper.c	Sat Apr 18 13:44:53 2020
@@ -0,0 +1,17 @@
+#include "t_mprotect_helper.h"
+
+int
+return_1(void)
+{
+	return 1;
+}
+int
+return_2(void)
+{
+	return 2;
+}
+int
+return_3(void)
+{
+	return 3;
+}

Reply via email to