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;
+}