Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Jan 2018 21:45:54 +0000 (UTC)
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r328266 - in head: contrib/netbsd-tests/lib/libc/sys lib/libc/sys
Message-ID:  <201801222145.w0MLjsAm063500@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Mon Jan 22 21:45:54 2018
New Revision: 328266
URL: https://svnweb.freebsd.org/changeset/base/328266

Log:
  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
  MFC after:	3 weeks
  Differential Revision:	https://reviews.freebsd.org/D13826

Modified:
  head/contrib/netbsd-tests/lib/libc/sys/t_mlock.c
  head/lib/libc/sys/mlock.2

Modified: head/contrib/netbsd-tests/lib/libc/sys/t_mlock.c
==============================================================================
--- head/contrib/netbsd-tests/lib/libc/sys/t_mlock.c	Mon Jan 22 20:56:21 2018	(r328265)
+++ head/contrib/netbsd-tests/lib/libc/sys/t_mlock.c	Mon Jan 22 21:45:54 2018	(r328266)
@@ -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: head/lib/libc/sys/mlock.2
==============================================================================
--- head/lib/libc/sys/mlock.2	Mon Jan 22 20:56:21 2018	(r328265)
+++ head/lib/libc/sys/mlock.2	Mon Jan 22 21:45:54 2018	(r328266)
@@ -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



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