t_minherit.c revision 272345
1259698Sdim/* $NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $ */ 2259698Sdim 3259698Sdim/*- 4259698Sdim * Copyright (c) 2014 The NetBSD Foundation, Inc. 5259698Sdim * All rights reserved. 6259698Sdim * 7259698Sdim * This code is derived from software contributed to The NetBSD Foundation 8259698Sdim * by Christos Zoulas 9259698Sdim * 10259698Sdim * Redistribution and use in source and binary forms, with or without 11259698Sdim * modification, are permitted provided that the following conditions 12259698Sdim * are met: 13259698Sdim * 1. Redistributions of source code must retain the above copyright 14259698Sdim * notice, this list of conditions and the following disclaimer. 15259698Sdim * 2. Redistributions in binary form must reproduce the above copyright 16259698Sdim * notice, this list of conditions and the following disclaimer in the 17259698Sdim * documentation and/or other materials provided with the distribution. 18259698Sdim * 19259698Sdim * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20259698Sdim * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21259698Sdim * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22259698Sdim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23259698Sdim * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24259698Sdim * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25259698Sdim * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26259698Sdim * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27259698Sdim * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28259698Sdim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29259698Sdim * POSSIBILITY OF SUCH DAMAGE. 30259698Sdim */ 31259698Sdim#include <sys/cdefs.h> 32259698Sdim__RCSID("$NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $"); 33259698Sdim 34259698Sdim#include <sys/param.h> 35259698Sdim#include <sys/mman.h> 36259698Sdim#include <sys/sysctl.h> 37259698Sdim#include <sys/wait.h> 38259698Sdim 39259698Sdim#include <errno.h> 40259698Sdim#include <fcntl.h> 41259698Sdim#include <stdlib.h> 42259698Sdim#include <string.h> 43259698Sdim#include <unistd.h> 44259698Sdim 45259698Sdim#include <atf-c.h> 46259698Sdim 47259698Sdimstatic long page; 48259698Sdim 49259698Sdimstatic void * 50259698Sdimmakemap(int v, int f) { 51259698Sdim void *map = mmap(NULL, page, PROT_READ|PROT_WRITE, 52259698Sdim MAP_SHARED|MAP_ANON, -1, 0); 53259698Sdim ATF_REQUIRE(map != MAP_FAILED); 54259698Sdim memset(map, v, page); 55259698Sdim if (f != 666) 56259698Sdim ATF_REQUIRE(minherit(map, page, f) == 0); 57259698Sdim else 58259698Sdim ATF_REQUIRE(minherit(map, page, f) == -1); 59259698Sdim return map; 60259698Sdim} 61259698Sdim 62259698SdimATF_TC(minherit_copy); 63259698SdimATF_TC_HEAD(minherit_copy, tc) 64259698Sdim{ 65259698Sdim atf_tc_set_md_var(tc, "descr", 66259698Sdim "Test for MAP_INHERIT_COPY from minherit(2)"); 67259698Sdim} 68259698Sdim 69259698SdimATF_TC_BODY(minherit_copy, tc) 70259698Sdim{ 71259698Sdim void *map1 = makemap(1, MAP_INHERIT_COPY); 72259698Sdim void *map2 = makemap(1, MAP_INHERIT_COPY); 73259698Sdim switch (fork()) { 74259698Sdim default: 75259698Sdim ATF_REQUIRE(wait(NULL) != -1); 76259698Sdim ATF_REQUIRE(memcmp(map1, map2, page) == 0); 77259698Sdim break; 78259698Sdim case -1: 79259698Sdim ATF_REQUIRE(0); 80259698Sdim break; 81259698Sdim case 0: 82259698Sdim ATF_REQUIRE(memcmp(map1, map2, page) == 0); 83259698Sdim memset(map1, 0, page); 84259698Sdim exit(0); 85259698Sdim } 86259698Sdim} 87259698Sdim 88259698SdimATF_TC(minherit_share); 89259698SdimATF_TC_HEAD(minherit_share, tc) 90259698Sdim{ 91259698Sdim atf_tc_set_md_var(tc, "descr", 92259698Sdim "Test for MAP_INHERIT_SHARE from minherit(2)"); 93259698Sdim} 94259698Sdim 95259698SdimATF_TC_BODY(minherit_share, tc) 96259698Sdim{ 97259698Sdim void *map1 = makemap(1, MAP_INHERIT_SHARE); 98259698Sdim void *map2 = makemap(1, MAP_INHERIT_SHARE); 99259698Sdim 100259698Sdim switch (fork()) { 101259698Sdim default: 102259698Sdim ATF_REQUIRE(wait(NULL) != -1); 103259698Sdim memset(map2, 0, page); 104259698Sdim ATF_REQUIRE(memcmp(map1, map2, page) == 0); 105259698Sdim break; 106259698Sdim case -1: 107259698Sdim ATF_REQUIRE(0); 108259698Sdim break; 109259698Sdim case 0: 110259698Sdim ATF_REQUIRE(memcmp(map1, map2, page) == 0); 111259698Sdim memset(map1, 0, page); 112259698Sdim exit(0); 113259698Sdim } 114259698Sdim} 115259698Sdim 116259698Sdimstatic void 117259698Sdimsegv(int n) { 118259698Sdim _exit(n); 119259698Sdim} 120259698Sdim 121259698SdimATF_TC(minherit_none); 122259698SdimATF_TC_HEAD(minherit_none, tc) 123259698Sdim{ 124259698Sdim atf_tc_set_md_var(tc, "descr", 125259698Sdim "Test for MAP_INHERIT_NONE from minherit(2)"); 126259698Sdim} 127259698Sdim 128259698SdimATF_TC_BODY(minherit_none, tc) 129259698Sdim{ 130259698Sdim void *map1 = makemap(0, MAP_INHERIT_NONE); 131259698Sdim int status; 132259698Sdim 133259698Sdim switch (fork()) { 134259698Sdim default: 135259698Sdim ATF_REQUIRE(wait(&status) != -1); 136259698Sdim ATF_REQUIRE(WEXITSTATUS(status) == SIGSEGV); 137259698Sdim break; 138259698Sdim case -1: 139259698Sdim ATF_REQUIRE(0); 140259698Sdim break; 141259698Sdim case 0: 142259698Sdim ATF_REQUIRE(signal(SIGSEGV, segv) != SIG_ERR); 143259698Sdim memset(map1, 0, page); 144259698Sdim exit(0); 145259698Sdim } 146259698Sdim} 147259698Sdim 148259698SdimATF_TC(minherit_zero); 149259698SdimATF_TC_HEAD(minherit_zero, tc) 150259698Sdim{ 151259698Sdim atf_tc_set_md_var(tc, "descr", 152259698Sdim "Test for MAP_INHERIT_ZERO from minherit(2)"); 153259698Sdim} 154259698Sdim 155259698SdimATF_TC_BODY(minherit_zero, tc) 156259698Sdim{ 157259698Sdim void *map1 = makemap(1, MAP_INHERIT_ZERO); 158259698Sdim void *map2 = makemap(0, MAP_INHERIT_SHARE); 159259698Sdim 160259698Sdim switch (fork()) { 161259698Sdim default: 162259698Sdim ATF_REQUIRE(wait(NULL) != -1); 163259698Sdim memset(map2, 1, page); 164259698Sdim ATF_REQUIRE(memcmp(map1, map2, page) == 0); 165259698Sdim break; 166259698Sdim case -1: 167259698Sdim ATF_REQUIRE(0); 168259698Sdim break; 169259698Sdim case 0: 170259698Sdim ATF_REQUIRE(memcmp(map1, map2, page) == 0); 171259698Sdim memset(map1, 2, page); 172259698Sdim exit(0); 173259698Sdim } 174259698Sdim} 175 176ATF_TC(minherit_bad); 177ATF_TC_HEAD(minherit_bad, tc) 178{ 179 atf_tc_set_md_var(tc, "descr", 180 "Test for bad minherit(2)"); 181} 182 183ATF_TC_BODY(minherit_bad, tc) 184{ 185 (void)makemap(0, 666); 186} 187 188ATF_TP_ADD_TCS(tp) 189{ 190 page = sysconf(_SC_PAGESIZE); 191 ATF_REQUIRE(page >= 0); 192 193 ATF_TP_ADD_TC(tp, minherit_copy); 194 ATF_TP_ADD_TC(tp, minherit_share); 195 ATF_TP_ADD_TC(tp, minherit_none); 196 ATF_TP_ADD_TC(tp, minherit_zero); 197 ATF_TP_ADD_TC(tp, minherit_bad); 198 199 return atf_no_error(); 200} 201