svn commit: r329790 - in stable/11: contrib/netbsd-tests/lib/libc/sys lib/libc/sys

Alan Somers asomers at FreeBSD.org
Thu Feb 22 02:14:44 UTC 2018


Author: asomers
Date: Thu Feb 22 02:14:43 2018
New Revision: 329790
URL: https://svnweb.freebsd.org/changeset/base/329790

Log:
  MFC r328266:
  
  mlock(2): correct documentation for error conditions.
  
  The man page is years out of date regarding errors. Our implementation _does_
  allow unaligned addresses, and it _does_not_ check for negative lengths,
  because the length is unsigned. It checks for overflow instead.
  
  Update the tests accordingly.
  
  Reviewed by:	bcr
  Differential Revision:	https://reviews.freebsd.org/D13826

Modified:
  stable/11/contrib/netbsd-tests/lib/libc/sys/t_mlock.c
  stable/11/lib/libc/sys/mlock.2
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/contrib/netbsd-tests/lib/libc/sys/t_mlock.c
==============================================================================
--- stable/11/contrib/netbsd-tests/lib/libc/sys/t_mlock.c	Thu Feb 22 02:12:47 2018	(r329789)
+++ stable/11/contrib/netbsd-tests/lib/libc/sys/t_mlock.c	Thu Feb 22 02:14:43 2018	(r329790)
@@ -133,38 +133,43 @@ ATF_TC_BODY(mlock_err, tc)
 	ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)0, page) == -1);
 
 	errno = 0;
-	ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)-1, page) == -1);
-
-	errno = 0;
 	ATF_REQUIRE_ERRNO(ENOMEM, munlock(NULL, page) == -1);
 
 	errno = 0;
 	ATF_REQUIRE_ERRNO(ENOMEM, munlock((char *)0, page) == -1);
 
+#ifdef __FreeBSD__
+	/* Wrap around should return EINVAL */
 	errno = 0;
+	ATF_REQUIRE_ERRNO(EINVAL, mlock((char *)-1, page) == -1);
+	errno = 0;
+	ATF_REQUIRE_ERRNO(EINVAL, munlock((char *)-1, page) == -1);
+#else
+	errno = 0;
+	ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)-1, page) == -1);
+	errno = 0;
 	ATF_REQUIRE_ERRNO(ENOMEM, munlock((char *)-1, page) == -1);
+#endif
 
-	buf = malloc(page);
+	buf = malloc(page);	/* Get a valid address */
 	ATF_REQUIRE(buf != NULL);
-
-	/*
-	 * unlocking memory that is not locked is an error...
-	 */
-
+#ifdef __FreeBSD__
 	errno = 0;
-	ATF_REQUIRE_ERRNO(ENOMEM, munlock(buf, page) == -1);
+	/* Wrap around should return EINVAL */
+	ATF_REQUIRE_ERRNO(EINVAL, mlock(buf, -page) == -1);
+	errno = 0;
+	ATF_REQUIRE_ERRNO(EINVAL, munlock(buf, -page) == -1);
+#else
+	errno = 0;
+	ATF_REQUIRE_ERRNO(ENOMEM, mlock(buf, -page) == -1);
+	errno = 0;
+	ATF_REQUIRE_ERRNO(ENOMEM, munlock(buf, -page) == -1);
+#endif
+	(void)free(buf);
 
 /* There is no sbrk on AArch64 and RISC-V */
 #if !defined(__aarch64__) && !defined(__riscv__)
 	/*
-	 * These are permitted to fail (EINVAL) but do not on NetBSD
-	 */
-	ATF_REQUIRE(mlock((void *)(((uintptr_t)buf) + page/3), page/5) == 0);
-	ATF_REQUIRE(munlock((void *)(((uintptr_t)buf) + page/3), page/5) == 0);
-
-	(void)free(buf);
-
-	/*
 	 * Try to create a pointer to an unmapped page - first after current
 	 * brk will likely do.
 	 */
@@ -360,6 +365,80 @@ ATF_TC_CLEANUP(mlock_nested, tc)
 }
 #endif
 
+#ifdef __FreeBSD__
+ATF_TC_WITH_CLEANUP(mlock_unaligned);
+#else
+ATF_TC(mlock_unaligned);
+#endif
+ATF_TC_HEAD(mlock_unaligned, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Test that mlock(2) can lock page-unaligned memory");
+#ifdef __FreeBSD__
+	atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects");
+	atf_tc_set_md_var(tc, "require.user", "root");
+#endif
+}
+
+ATF_TC_BODY(mlock_unaligned, tc)
+{
+	void *buf, *addr;
+
+#ifdef __FreeBSD__
+	/* Set max_wired really really high to avoid EAGAIN */
+	set_vm_max_wired(INT_MAX);
+#endif
+
+	buf = malloc(page);
+	ATF_REQUIRE(buf != NULL);
+
+	if ((uintptr_t)buf & ((uintptr_t)page - 1))
+		addr = buf;
+	else
+		addr = (void *)(((uintptr_t)buf) + page/3);
+
+	ATF_REQUIRE_EQ(mlock(addr, page/5), 0);
+	ATF_REQUIRE_EQ(munlock(addr, page/5), 0);
+
+	(void)free(buf);
+}
+
+#ifdef __FreeBSD__
+ATF_TC_CLEANUP(mlock_unaligned, tc)
+{
+
+	restore_vm_max_wired();
+}
+#endif
+
+ATF_TC(munlock_unlocked);
+ATF_TC_HEAD(munlock_unlocked, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+#ifdef __FreeBSD__
+	    "munlock(2) accepts unlocked memory");
+#else
+	    "munlock(2) of unlocked memory is an error");
+#endif
+	atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(munlock_unlocked, tc)
+{
+	void *buf;
+
+	buf = malloc(page);
+	ATF_REQUIRE(buf != NULL);
+
+#ifdef __FreeBSD__
+	ATF_REQUIRE_EQ(munlock(buf, page), 0);
+#else
+	errno = 0;
+	ATF_REQUIRE_ERRNO(ENOMEM, munlock(buf, page) == -1);
+#endif
+	(void)free(buf);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 
@@ -371,6 +450,8 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, mlock_limits);
 	ATF_TP_ADD_TC(tp, mlock_mmap);
 	ATF_TP_ADD_TC(tp, mlock_nested);
+	ATF_TP_ADD_TC(tp, mlock_unaligned);
+	ATF_TP_ADD_TC(tp, munlock_unlocked);
 
 	return atf_no_error();
 }

Modified: stable/11/lib/libc/sys/mlock.2
==============================================================================
--- stable/11/lib/libc/sys/mlock.2	Thu Feb 22 02:12:47 2018	(r329789)
+++ stable/11/lib/libc/sys/mlock.2	Thu Feb 22 02:14:43 2018	(r329790)
@@ -28,7 +28,7 @@
 .\"	@(#)mlock.2	8.2 (Berkeley) 12/11/93
 .\" $FreeBSD$
 .\"
-.Dd May 17, 2014
+.Dd Jan 22, 2018
 .Dt MLOCK 2
 .Os
 .Sh NAME
@@ -125,7 +125,7 @@ will fail if:
 .Va security.bsd.unprivileged_mlock
 is set to 0 and the caller is not the super-user.
 .It Bq Er EINVAL
-The address given is not page aligned or the length is negative.
+The address range given wraps around zero.
 .It Bq Er EAGAIN
 Locking the indicated range would exceed the system limit for locked memory.
 .It Bq Er ENOMEM
@@ -143,7 +143,7 @@ will fail if:
 .Va security.bsd.unprivileged_mlock
 is set to 0 and the caller is not the super-user.
 .It Bq Er EINVAL
-The address given is not page aligned or the length is negative.
+The address range given wraps around zero.
 .It Bq Er ENOMEM
 Some or all of the address range specified by the addr and len
 arguments does not correspond to valid mapped pages in the address space


More information about the svn-src-all mailing list