1 /* $OpenBSD: t_minherit.c,v 1.1 2021/09/02 12:40:44 mbuhl Exp $ */ 2 /* $NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $ */ 3 4 /*- 5 * Copyright (c) 2014 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Christos Zoulas 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 #include "macros.h" 33 34 #include <sys/cdefs.h> 35 __RCSID("$NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $"); 36 37 #include <sys/param.h> 38 #include <sys/mman.h> 39 #include <sys/sysctl.h> 40 #include <sys/wait.h> 41 42 #include <errno.h> 43 #include <fcntl.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <unistd.h> 47 48 #include "atf-c.h" 49 50 static long page; 51 52 static void * 53 makemap(int v, int f) { 54 void *map = mmap(NULL, page, PROT_READ|PROT_WRITE, 55 MAP_SHARED|MAP_ANON, -1, 0); 56 ATF_REQUIRE(map != MAP_FAILED); 57 memset(map, v, page); 58 if (f != 666) 59 ATF_REQUIRE(minherit(map, page, f) == 0); 60 else 61 ATF_REQUIRE(minherit(map, page, f) == -1); 62 return map; 63 } 64 65 ATF_TC(minherit_copy); 66 ATF_TC_HEAD(minherit_copy, tc) 67 { 68 atf_tc_set_md_var(tc, "descr", 69 "Test for MAP_INHERIT_COPY from minherit(2)"); 70 } 71 72 ATF_TC_BODY(minherit_copy, tc) 73 { 74 void *map1 = makemap(1, MAP_INHERIT_COPY); 75 void *map2 = makemap(1, MAP_INHERIT_COPY); 76 switch (fork()) { 77 default: 78 ATF_REQUIRE(wait(NULL) != -1); 79 ATF_REQUIRE(memcmp(map1, map2, page) == 0); 80 break; 81 case -1: 82 ATF_REQUIRE(0); 83 break; 84 case 0: 85 ATF_REQUIRE(memcmp(map1, map2, page) == 0); 86 memset(map1, 0, page); 87 exit(0); 88 } 89 } 90 91 ATF_TC(minherit_share); 92 ATF_TC_HEAD(minherit_share, tc) 93 { 94 atf_tc_set_md_var(tc, "descr", 95 "Test for MAP_INHERIT_SHARE from minherit(2)"); 96 } 97 98 ATF_TC_BODY(minherit_share, tc) 99 { 100 void *map1 = makemap(1, MAP_INHERIT_SHARE); 101 void *map2 = makemap(1, MAP_INHERIT_SHARE); 102 103 switch (fork()) { 104 default: 105 ATF_REQUIRE(wait(NULL) != -1); 106 memset(map2, 0, page); 107 ATF_REQUIRE(memcmp(map1, map2, page) == 0); 108 break; 109 case -1: 110 ATF_REQUIRE(0); 111 break; 112 case 0: 113 ATF_REQUIRE(memcmp(map1, map2, page) == 0); 114 memset(map1, 0, page); 115 exit(0); 116 } 117 } 118 119 static void 120 segv(int n) { 121 _exit(n); 122 } 123 124 ATF_TC(minherit_none); 125 ATF_TC_HEAD(minherit_none, tc) 126 { 127 atf_tc_set_md_var(tc, "descr", 128 "Test for MAP_INHERIT_NONE from minherit(2)"); 129 } 130 131 ATF_TC_BODY(minherit_none, tc) 132 { 133 void *map1 = makemap(0, MAP_INHERIT_NONE); 134 int status; 135 136 switch (fork()) { 137 default: 138 ATF_REQUIRE(wait(&status) != -1); 139 ATF_REQUIRE(WEXITSTATUS(status) == SIGSEGV); 140 break; 141 case -1: 142 ATF_REQUIRE(0); 143 break; 144 case 0: 145 ATF_REQUIRE(signal(SIGSEGV, segv) != SIG_ERR); 146 memset(map1, 0, page); 147 exit(0); 148 } 149 } 150 151 ATF_TC(minherit_zero); 152 ATF_TC_HEAD(minherit_zero, tc) 153 { 154 atf_tc_set_md_var(tc, "descr", 155 "Test for MAP_INHERIT_ZERO from minherit(2)"); 156 } 157 158 ATF_TC_BODY(minherit_zero, tc) 159 { 160 void *map1 = makemap(1, MAP_INHERIT_ZERO); 161 void *map2 = makemap(0, MAP_INHERIT_SHARE); 162 163 switch (fork()) { 164 default: 165 ATF_REQUIRE(wait(NULL) != -1); 166 memset(map2, 1, page); 167 ATF_REQUIRE(memcmp(map1, map2, page) == 0); 168 break; 169 case -1: 170 ATF_REQUIRE(0); 171 break; 172 case 0: 173 ATF_REQUIRE(memcmp(map1, map2, page) == 0); 174 memset(map1, 2, page); 175 exit(0); 176 } 177 } 178 179 ATF_TC(minherit_bad); 180 ATF_TC_HEAD(minherit_bad, tc) 181 { 182 atf_tc_set_md_var(tc, "descr", 183 "Test for bad minherit(2)"); 184 } 185 186 ATF_TC_BODY(minherit_bad, tc) 187 { 188 (void)makemap(0, 666); 189 } 190 191 ATF_TP_ADD_TCS(tp) 192 { 193 page = sysconf(_SC_PAGESIZE); 194 ATF_REQUIRE(page >= 0); 195 196 ATF_TP_ADD_TC(tp, minherit_copy); 197 ATF_TP_ADD_TC(tp, minherit_share); 198 ATF_TP_ADD_TC(tp, minherit_none); 199 ATF_TP_ADD_TC(tp, minherit_zero); 200 ATF_TP_ADD_TC(tp, minherit_bad); 201 202 return atf_no_error(); 203 } 204