1272343Sngie/* $NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $ */ 2272343Sngie 3272343Sngie/*- 4272343Sngie * Copyright (c) 2014 The NetBSD Foundation, Inc. 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * This code is derived from software contributed to The NetBSD Foundation 8272343Sngie * by Christos Zoulas 9272343Sngie * 10272343Sngie * Redistribution and use in source and binary forms, with or without 11272343Sngie * modification, are permitted provided that the following conditions 12272343Sngie * are met: 13272343Sngie * 1. Redistributions of source code must retain the above copyright 14272343Sngie * notice, this list of conditions and the following disclaimer. 15272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 16272343Sngie * notice, this list of conditions and the following disclaimer in the 17272343Sngie * documentation and/or other materials provided with the distribution. 18272343Sngie * 19272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22272343Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29272343Sngie * POSSIBILITY OF SUCH DAMAGE. 30272343Sngie */ 31272343Sngie#include <sys/cdefs.h> 32272343Sngie__RCSID("$NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $"); 33272343Sngie 34272343Sngie#include <sys/param.h> 35272343Sngie#include <sys/mman.h> 36272343Sngie#include <sys/sysctl.h> 37272343Sngie#include <sys/wait.h> 38272343Sngie 39272343Sngie#include <errno.h> 40272343Sngie#include <fcntl.h> 41272343Sngie#include <stdlib.h> 42272343Sngie#include <string.h> 43272343Sngie#include <unistd.h> 44272343Sngie 45272343Sngie#include <atf-c.h> 46272343Sngie 47272343Sngiestatic long page; 48272343Sngie 49272343Sngiestatic void * 50272343Sngiemakemap(int v, int f) { 51272343Sngie void *map = mmap(NULL, page, PROT_READ|PROT_WRITE, 52272343Sngie MAP_SHARED|MAP_ANON, -1, 0); 53272343Sngie ATF_REQUIRE(map != MAP_FAILED); 54272343Sngie memset(map, v, page); 55272343Sngie if (f != 666) 56272343Sngie ATF_REQUIRE(minherit(map, page, f) == 0); 57272343Sngie else 58272343Sngie ATF_REQUIRE(minherit(map, page, f) == -1); 59272343Sngie return map; 60272343Sngie} 61272343Sngie 62272343SngieATF_TC(minherit_copy); 63272343SngieATF_TC_HEAD(minherit_copy, tc) 64272343Sngie{ 65272343Sngie atf_tc_set_md_var(tc, "descr", 66272343Sngie "Test for MAP_INHERIT_COPY from minherit(2)"); 67272343Sngie} 68272343Sngie 69272343SngieATF_TC_BODY(minherit_copy, tc) 70272343Sngie{ 71272343Sngie void *map1 = makemap(1, MAP_INHERIT_COPY); 72272343Sngie void *map2 = makemap(1, MAP_INHERIT_COPY); 73272343Sngie switch (fork()) { 74272343Sngie default: 75272343Sngie ATF_REQUIRE(wait(NULL) != -1); 76272343Sngie ATF_REQUIRE(memcmp(map1, map2, page) == 0); 77272343Sngie break; 78272343Sngie case -1: 79272343Sngie ATF_REQUIRE(0); 80272343Sngie break; 81272343Sngie case 0: 82272343Sngie ATF_REQUIRE(memcmp(map1, map2, page) == 0); 83272343Sngie memset(map1, 0, page); 84272343Sngie exit(0); 85272343Sngie } 86272343Sngie} 87272343Sngie 88272343SngieATF_TC(minherit_share); 89272343SngieATF_TC_HEAD(minherit_share, tc) 90272343Sngie{ 91272343Sngie atf_tc_set_md_var(tc, "descr", 92272343Sngie "Test for MAP_INHERIT_SHARE from minherit(2)"); 93272343Sngie} 94272343Sngie 95272343SngieATF_TC_BODY(minherit_share, tc) 96272343Sngie{ 97272343Sngie void *map1 = makemap(1, MAP_INHERIT_SHARE); 98272343Sngie void *map2 = makemap(1, MAP_INHERIT_SHARE); 99272343Sngie 100272343Sngie switch (fork()) { 101272343Sngie default: 102272343Sngie ATF_REQUIRE(wait(NULL) != -1); 103272343Sngie memset(map2, 0, page); 104272343Sngie ATF_REQUIRE(memcmp(map1, map2, page) == 0); 105272343Sngie break; 106272343Sngie case -1: 107272343Sngie ATF_REQUIRE(0); 108272343Sngie break; 109272343Sngie case 0: 110272343Sngie ATF_REQUIRE(memcmp(map1, map2, page) == 0); 111272343Sngie memset(map1, 0, page); 112272343Sngie exit(0); 113272343Sngie } 114272343Sngie} 115272343Sngie 116272343Sngiestatic void 117272343Sngiesegv(int n) { 118272343Sngie _exit(n); 119272343Sngie} 120272343Sngie 121272343SngieATF_TC(minherit_none); 122272343SngieATF_TC_HEAD(minherit_none, tc) 123272343Sngie{ 124272343Sngie atf_tc_set_md_var(tc, "descr", 125272343Sngie "Test for MAP_INHERIT_NONE from minherit(2)"); 126272343Sngie} 127272343Sngie 128272343SngieATF_TC_BODY(minherit_none, tc) 129272343Sngie{ 130272343Sngie void *map1 = makemap(0, MAP_INHERIT_NONE); 131272343Sngie int status; 132272343Sngie 133272343Sngie switch (fork()) { 134272343Sngie default: 135272343Sngie ATF_REQUIRE(wait(&status) != -1); 136272343Sngie ATF_REQUIRE(WEXITSTATUS(status) == SIGSEGV); 137272343Sngie break; 138272343Sngie case -1: 139272343Sngie ATF_REQUIRE(0); 140272343Sngie break; 141272343Sngie case 0: 142272343Sngie ATF_REQUIRE(signal(SIGSEGV, segv) != SIG_ERR); 143272343Sngie memset(map1, 0, page); 144272343Sngie exit(0); 145272343Sngie } 146272343Sngie} 147272343Sngie 148272343SngieATF_TC(minherit_zero); 149272343SngieATF_TC_HEAD(minherit_zero, tc) 150272343Sngie{ 151272343Sngie atf_tc_set_md_var(tc, "descr", 152272343Sngie "Test for MAP_INHERIT_ZERO from minherit(2)"); 153272343Sngie} 154272343Sngie 155272343SngieATF_TC_BODY(minherit_zero, tc) 156272343Sngie{ 157272343Sngie void *map1 = makemap(1, MAP_INHERIT_ZERO); 158272343Sngie void *map2 = makemap(0, MAP_INHERIT_SHARE); 159272343Sngie 160272343Sngie switch (fork()) { 161272343Sngie default: 162272343Sngie ATF_REQUIRE(wait(NULL) != -1); 163272343Sngie memset(map2, 1, page); 164272343Sngie ATF_REQUIRE(memcmp(map1, map2, page) == 0); 165272343Sngie break; 166272343Sngie case -1: 167272343Sngie ATF_REQUIRE(0); 168272343Sngie break; 169272343Sngie case 0: 170272343Sngie ATF_REQUIRE(memcmp(map1, map2, page) == 0); 171272343Sngie memset(map1, 2, page); 172272343Sngie exit(0); 173272343Sngie } 174272343Sngie} 175272343Sngie 176272343SngieATF_TC(minherit_bad); 177272343SngieATF_TC_HEAD(minherit_bad, tc) 178272343Sngie{ 179272343Sngie atf_tc_set_md_var(tc, "descr", 180272343Sngie "Test for bad minherit(2)"); 181272343Sngie} 182272343Sngie 183272343SngieATF_TC_BODY(minherit_bad, tc) 184272343Sngie{ 185272343Sngie (void)makemap(0, 666); 186272343Sngie} 187272343Sngie 188272343SngieATF_TP_ADD_TCS(tp) 189272343Sngie{ 190272343Sngie page = sysconf(_SC_PAGESIZE); 191272343Sngie ATF_REQUIRE(page >= 0); 192272343Sngie 193272343Sngie ATF_TP_ADD_TC(tp, minherit_copy); 194272343Sngie ATF_TP_ADD_TC(tp, minherit_share); 195272343Sngie ATF_TP_ADD_TC(tp, minherit_none); 196272343Sngie ATF_TP_ADD_TC(tp, minherit_zero); 197272343Sngie ATF_TP_ADD_TC(tp, minherit_bad); 198272343Sngie 199272343Sngie return atf_no_error(); 200272343Sngie} 201