Module Name:    src
Committed By:   gson
Date:           Wed Apr  6 10:02:55 UTC 2022

Modified Files:
        src/tests/lib/libc/sys: Makefile t_mmap.c

Log Message:
Add a regression test for PR kern/52239, "Changing protections of
already mmap'ed region can fail", based on the test program in the PR.


To generate a diff of this commit:
cvs rdiff -u -r1.70 -r1.71 src/tests/lib/libc/sys/Makefile
cvs rdiff -u -r1.16 -r1.17 src/tests/lib/libc/sys/t_mmap.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.70 src/tests/lib/libc/sys/Makefile:1.71
--- src/tests/lib/libc/sys/Makefile:1.70	Mon Nov  1 14:33:41 2021
+++ src/tests/lib/libc/sys/Makefile	Wed Apr  6 10:02:55 2022
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.70 2021/11/01 14:33:41 hannken Exp $
+# $NetBSD: Makefile,v 1.71 2022/04/06 10:02:55 gson Exp $
 
 MKMAN=	no
 
@@ -97,6 +97,7 @@ SRCS.t_mprotect=	t_mprotect.c ${SRCS_EXE
 
 LDADD.t_eventfd+=	-lpthread
 LDADD.t_getpid+=	-lpthread
+LDADD.t_mmap+=		-lpthread
 LDADD.t_timerfd+=	-lpthread
 
 LDADD.t_ptrace_sigchld+=	-pthread -lm

Index: src/tests/lib/libc/sys/t_mmap.c
diff -u src/tests/lib/libc/sys/t_mmap.c:1.16 src/tests/lib/libc/sys/t_mmap.c:1.17
--- src/tests/lib/libc/sys/t_mmap.c:1.16	Tue Apr  5 15:59:22 2022
+++ src/tests/lib/libc/sys/t_mmap.c	Wed Apr  6 10:02:55 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: t_mmap.c,v 1.16 2022/04/05 15:59:22 gson Exp $ */
+/* $NetBSD: t_mmap.c,v 1.17 2022/04/06 10:02:55 gson Exp $ */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -55,7 +55,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_mmap.c,v 1.16 2022/04/05 15:59:22 gson Exp $");
+__RCSID("$NetBSD: t_mmap.c,v 1.17 2022/04/06 10:02:55 gson Exp $");
 
 #include <sys/param.h>
 #include <sys/disklabel.h>
@@ -74,6 +74,7 @@ __RCSID("$NetBSD: t_mmap.c,v 1.16 2022/0
 #include <string.h>
 #include <unistd.h>
 #include <paths.h>
+#include <pthread.h>
 
 static long	page = 0;
 static char	path[] = "mmap";
@@ -413,6 +414,65 @@ ATF_TC_CLEANUP(mmap_prot_3, tc)
 	(void)unlink(path);
 }
 
+ATF_TC(mmap_reprotect_race);
+
+ATF_TC_HEAD(mmap_reprotect_race, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test for the race condition of PR 52239");
+}
+
+const int mmap_reprotect_race_npages = 13;
+const int mmap_reprotect_iterations = 1000000;
+
+static void *
+mmap_reprotect_race_thread(void *arg)
+{
+	int i, r;
+	void *p;
+
+	for (i = 0; i < mmap_reprotect_iterations; i++) {
+		/* Get some unrelated memory */
+		p = mmap(0, mmap_reprotect_race_npages * page,
+			 PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+		ATF_REQUIRE(p);
+		r = munmap(p, mmap_reprotect_race_npages * page);
+		ATF_REQUIRE(r == 0);
+	}
+	return 0;
+}
+
+ATF_TC_BODY(mmap_reprotect_race, tc)
+{
+	pthread_t thread;
+	void *p, *q;
+	int i, r;
+
+	r = pthread_create(&thread, 0, mmap_reprotect_race_thread, 0);
+	ATF_REQUIRE(r == 0);
+
+	for (i = 0; i < mmap_reprotect_iterations; i++) {
+		/* Get a placeholder region */
+		p = mmap(0, mmap_reprotect_race_npages * page,
+			 PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+		if (p == MAP_FAILED)
+			atf_tc_fail("mmap: %s", strerror(errno));
+
+		/* Upgrade placeholder to read/write access */
+		q = mmap(p, mmap_reprotect_race_npages * page,
+			 PROT_READ|PROT_WRITE,
+			 MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
+		if (q == MAP_FAILED)
+			atf_tc_fail("update mmap: %s", strerror(errno));
+		ATF_REQUIRE(q == p);
+
+		/* Free it */
+		r = munmap(q, mmap_reprotect_race_npages * page);
+		if (r != 0)
+			atf_tc_fail("munmap: %s", strerror(errno));
+	}
+	pthread_join(thread, NULL);
+}
+
 ATF_TC_WITH_CLEANUP(mmap_truncate);
 ATF_TC_HEAD(mmap_truncate, tc)
 {
@@ -570,6 +630,7 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, mmap_prot_1);
 	ATF_TP_ADD_TC(tp, mmap_prot_2);
 	ATF_TP_ADD_TC(tp, mmap_prot_3);
+	ATF_TP_ADD_TC(tp, mmap_reprotect_race);
 	ATF_TP_ADD_TC(tp, mmap_truncate);
 	ATF_TP_ADD_TC(tp, mmap_truncate_signal);
 	ATF_TP_ADD_TC(tp, mmap_va0);

Reply via email to