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:
parent
2149fa3ec8
commit
76f9d2759b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=328266
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user