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
This commit is contained in:
Alan Somers 2018-01-22 21:45:54 +00:00
parent 2149fa3ec8
commit 76f9d2759b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=328266
2 changed files with 102 additions and 21 deletions

View File

@ -132,38 +132,43 @@ ATF_TC_BODY(mlock_err, tc)
errno = 0;
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();
}

View File

@ -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