Changeset View
Changeset View
Standalone View
Standalone View
head/tests/sys/vm/mmap_test.c
Show All 23 Lines | |||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/types.h> | |||||
#include <atf-c.h> | |||||
#include <errno.h> | #include <errno.h> | ||||
#include <stdio.h> | |||||
#include <string.h> | |||||
static const struct { | static const struct { | ||||
void *addr; | void *addr; | ||||
int ok[2]; /* Depending on security.bsd.map_at_zero {0, !=0}. */ | int ok[2]; /* Depending on security.bsd.map_at_zero {0, !=0}. */ | ||||
} tests[] = { | } map_at_zero_tests[] = { | ||||
{ (void *)0, { 0, 1 } }, /* Test sysctl. */ | { (void *)0, { 0, 1 } }, /* Test sysctl. */ | ||||
{ (void *)1, { 0, 0 } }, | { (void *)1, { 0, 0 } }, | ||||
{ (void *)(PAGE_SIZE - 1), { 0, 0 } }, | { (void *)(PAGE_SIZE - 1), { 0, 0 } }, | ||||
{ (void *)PAGE_SIZE, { 1, 1 } }, | { (void *)PAGE_SIZE, { 1, 1 } }, | ||||
{ (void *)-1, { 0, 0 } }, | { (void *)-1, { 0, 0 } }, | ||||
{ (void *)(-PAGE_SIZE), { 0, 0 } }, | { (void *)(-PAGE_SIZE), { 0, 0 } }, | ||||
{ (void *)(-1 - PAGE_SIZE), { 0, 0 } }, | { (void *)(-1 - PAGE_SIZE), { 0, 0 } }, | ||||
{ (void *)(-1 - PAGE_SIZE - 1), { 0, 0 } }, | { (void *)(-1 - PAGE_SIZE - 1), { 0, 0 } }, | ||||
{ (void *)(0x1000 * PAGE_SIZE), { 1, 1 } }, | { (void *)(0x1000 * PAGE_SIZE), { 1, 1 } }, | ||||
}; | }; | ||||
#define MAP_AT_ZERO "security.bsd.map_at_zero" | #define MAP_AT_ZERO "security.bsd.map_at_zero" | ||||
int | ATF_TC_WITHOUT_HEAD(mmap__map_at_zero); | ||||
main(void) | ATF_TC_BODY(mmap__map_at_zero, tc) | ||||
{ | { | ||||
void *p; | void *p; | ||||
size_t len; | size_t len; | ||||
int i, error, mib[3], map_at_zero; | unsigned int i; | ||||
int map_at_zero; | |||||
error = 0; | |||||
/* Get the current sysctl value of security.bsd.map_at_zero. */ | |||||
len = sizeof(mib) / sizeof(*mib); | |||||
if (sysctlnametomib(MAP_AT_ZERO, mib, &len) == -1) { | |||||
printf("1..0 # SKIP: sysctlnametomib(\"%s\") failed: %s\n", | |||||
MAP_AT_ZERO, strerror(errno)); | |||||
return (0); | |||||
} | |||||
len = sizeof(map_at_zero); | len = sizeof(map_at_zero); | ||||
if (sysctl(mib, 3, &map_at_zero, &len, NULL, 0) == -1) { | if (sysctlbyname(MAP_AT_ZERO, &map_at_zero, &len, NULL, 0) == -1) { | ||||
printf("1..0 # SKIP: sysctl for %s failed: %s\n", MAP_AT_ZERO, | atf_tc_skip("sysctl for %s failed: %s\n", MAP_AT_ZERO, | ||||
strerror(errno)); | strerror(errno)); | ||||
return (0); | return; | ||||
} | } | ||||
/* Normalize to 0 or 1 for array access. */ | /* Normalize to 0 or 1 for array access. */ | ||||
map_at_zero = !!map_at_zero; | map_at_zero = !!map_at_zero; | ||||
printf("1..%zu\n", nitems(tests)); | for (i = 0; i < nitems(map_at_zero_tests); i++) { | ||||
for (i = 0; i < (int)nitems(tests); i++) { | p = mmap((void *)map_at_zero_tests[i].addr, PAGE_SIZE, | ||||
p = mmap((void *)tests[i].addr, PAGE_SIZE, | |||||
PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_FIXED, | PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_FIXED, | ||||
-1, 0); | -1, 0); | ||||
if (p == MAP_FAILED) { | if (p == MAP_FAILED) { | ||||
if (tests[i].ok[map_at_zero] != 0) | ATF_CHECK_MSG(map_at_zero_tests[i].ok[map_at_zero] == 0, | ||||
error++; | "mmap(%p, ...) failed", map_at_zero_tests[i].addr); | ||||
printf("%sok %d # mmap(%p, ...) failed\n", | |||||
tests[i].ok[map_at_zero] == 0 ? "" : "not ", | |||||
i + 1, | |||||
tests[i].addr); | |||||
} else { | } else { | ||||
if (tests[i].ok[map_at_zero] != 1) | ATF_CHECK_MSG(map_at_zero_tests[i].ok[map_at_zero] == 1, | ||||
error++; | "mmap(%p, ...) succeeded: p=%p\n", | ||||
printf("%sok %d # mmap(%p, ...) succeeded: p=%p\n", | map_at_zero_tests[i].addr, p); | ||||
tests[i].ok[map_at_zero] == 1 ? "" : "not ", | |||||
i + 1, | |||||
tests[i].addr, p); | |||||
} | } | ||||
} | } | ||||
} | |||||
return (error != 0); | ATF_TP_ADD_TCS(tp) | ||||
{ | |||||
ATF_TP_ADD_TC(tp, mmap__map_at_zero); | |||||
return (atf_no_error()); | |||||
} | } |