From 8ca4b045f398a1a997efed97f3d2b9066a47623d Mon Sep 17 00:00:00 2001 From: jhb Date: Thu, 1 Oct 2015 22:17:27 +0000 Subject: [PATCH] MFC 286370: Add various tests to ensure that invalid arguments passed to mmap() trigger failures. Note: most of the tests that should provoke an EINVAL error do not pass on stable/10 as stable/10 does not have the changes that added more strict parameter checking to mmap(). Those changes will not be merged to stable/10, so I have disabled them via #if 0 with a comment explaining why. git-svn-id: svn://svn.freebsd.org/base/stable/10@288466 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- tests/sys/vm/mmap_test.c | 80 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/tests/sys/vm/mmap_test.c b/tests/sys/vm/mmap_test.c index 74e163495..8e99e729f 100644 --- a/tests/sys/vm/mmap_test.c +++ b/tests/sys/vm/mmap_test.c @@ -32,6 +32,10 @@ #include #include +#include +#include +#include +#include static const struct { void *addr; @@ -83,10 +87,86 @@ ATF_TC_BODY(mmap__map_at_zero, tc) } } +static void +checked_mmap(int prot, int flags, int fd, int error, const char *msg) +{ + void *p; + + p = mmap(NULL, getpagesize(), prot, flags, fd, 0); + if (p == MAP_FAILED) { + if (error == 0) + ATF_CHECK_MSG(0, "%s failed with errno %d", msg, + errno); + else + ATF_CHECK_EQ_MSG(error, errno, + "%s failed with wrong errno %d (expected %d)", msg, + errno, error); + } else { + ATF_CHECK_MSG(error == 0, "%s succeeded", msg); + munmap(p, getpagesize()); + } +} + +ATF_TC_WITHOUT_HEAD(mmap__bad_arguments); +ATF_TC_BODY(mmap__bad_arguments, tc) +{ + int fd; + + ATF_REQUIRE((fd = shm_open(SHM_ANON, O_RDWR, 0644)) >= 0); + ATF_REQUIRE(ftruncate(fd, getpagesize()) == 0); + + /* These should work. */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON, -1, 0, + "simple MAP_ANON"); + checked_mmap(PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0, + "simple shm fd shared"); + checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0, + "simple shm fd private"); + +#if 0 + /* + * These tests do not fail without r271635 and followup fixes. + * Those changes will not be merged to stable/10 since they + * are potentially disruptive. + */ + + /* Extra PROT flags. */ + checked_mmap(PROT_READ | PROT_WRITE | 0x100000, MAP_ANON, -1, EINVAL, + "MAP_ANON with extra PROT flags"); + checked_mmap(0xffff, MAP_SHARED, fd, EINVAL, + "shm fd with garbage PROT"); + + /* Undefined flag. */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_RESERVED0080, -1, + EINVAL, "Undefined flag"); + + /* Both MAP_SHARED and MAP_PRIVATE */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | + MAP_SHARED, -1, EINVAL, "MAP_ANON with both SHARED and PRIVATE"); + checked_mmap(PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_SHARED, fd, + EINVAL, "shm fd with both SHARED and PRIVATE"); + + /* At least one of MAP_SHARED or MAP_PRIVATE without ANON */ + checked_mmap(PROT_READ | PROT_WRITE, 0, fd, EINVAL, + "shm fd without sharing flag"); +#endif + + /* MAP_ANON with either sharing flag (impacts fork). */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0, + "shared MAP_ANON"); + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0, + "private MAP_ANON"); + + /* MAP_ANON should require an fd of -1. */ + checked_mmap(PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, EINVAL, + "MAP_ANON with fd != -1"); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, mmap__map_at_zero); + ATF_TP_ADD_TC(tp, mmap__bad_arguments); return (atf_no_error()); } -- 2.45.0