1*9f9c9b22SMark Johnston /*- 2*9f9c9b22SMark Johnston * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*9f9c9b22SMark Johnston * 4*9f9c9b22SMark Johnston * Copyright (c) 2018 Mark Johnston <markj@FreeBSD.org> 5*9f9c9b22SMark Johnston * 6*9f9c9b22SMark Johnston * Redistribution and use in source and binary forms, with or without 7*9f9c9b22SMark Johnston * modification, are permitted provided that the following conditions 8*9f9c9b22SMark Johnston * are met: 9*9f9c9b22SMark Johnston * 1. Redistributions of source code must retain the above copyright 10*9f9c9b22SMark Johnston * notice, this list of conditions and the following disclaimer. 11*9f9c9b22SMark Johnston * 2. Redistributions in binary form must reproduce the above copyright 12*9f9c9b22SMark Johnston * notice, this list of conditions and the following disclaimer in the 13*9f9c9b22SMark Johnston * documentation and/or other materials provided with the distribution. 14*9f9c9b22SMark Johnston * 15*9f9c9b22SMark Johnston * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*9f9c9b22SMark Johnston * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*9f9c9b22SMark Johnston * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*9f9c9b22SMark Johnston * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*9f9c9b22SMark Johnston * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*9f9c9b22SMark Johnston * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*9f9c9b22SMark Johnston * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*9f9c9b22SMark Johnston * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*9f9c9b22SMark Johnston * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*9f9c9b22SMark Johnston * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*9f9c9b22SMark Johnston * SUCH DAMAGE. 26*9f9c9b22SMark Johnston */ 27*9f9c9b22SMark Johnston 28*9f9c9b22SMark Johnston #include <sys/cdefs.h> 29*9f9c9b22SMark Johnston __FBSDID("$FreeBSD$"); 30*9f9c9b22SMark Johnston 31*9f9c9b22SMark Johnston #include <sys/param.h> 32*9f9c9b22SMark Johnston #include <sys/mman.h> 33*9f9c9b22SMark Johnston 34*9f9c9b22SMark Johnston #include <errno.h> 35*9f9c9b22SMark Johnston #include <stdint.h> 36*9f9c9b22SMark Johnston #include <string.h> 37*9f9c9b22SMark Johnston #include <unistd.h> 38*9f9c9b22SMark Johnston 39*9f9c9b22SMark Johnston #include <atf-c.h> 40*9f9c9b22SMark Johnston 41*9f9c9b22SMark Johnston ATF_TC(brk_basic); 42*9f9c9b22SMark Johnston ATF_TC_HEAD(brk_basic, tc) 43*9f9c9b22SMark Johnston { 44*9f9c9b22SMark Johnston atf_tc_set_md_var(tc, "descr", "Verify basic brk() functionality"); 45*9f9c9b22SMark Johnston } 46*9f9c9b22SMark Johnston ATF_TC_BODY(brk_basic, tc) 47*9f9c9b22SMark Johnston { 48*9f9c9b22SMark Johnston void *oldbrk, *newbrk; 49*9f9c9b22SMark Johnston int error; 50*9f9c9b22SMark Johnston 51*9f9c9b22SMark Johnston /* Reset the break. */ 52*9f9c9b22SMark Johnston error = brk(0); 53*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno)); 54*9f9c9b22SMark Johnston 55*9f9c9b22SMark Johnston oldbrk = sbrk(0); 56*9f9c9b22SMark Johnston ATF_REQUIRE(oldbrk != (void *)-1); 57*9f9c9b22SMark Johnston 58*9f9c9b22SMark Johnston /* Try to allocate a page. */ 59*9f9c9b22SMark Johnston error = brk((void *)((intptr_t)oldbrk + PAGE_SIZE * 2)); 60*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno)); 61*9f9c9b22SMark Johnston 62*9f9c9b22SMark Johnston /* 63*9f9c9b22SMark Johnston * Attempt to set the break below minbrk. This should have no effect. 64*9f9c9b22SMark Johnston */ 65*9f9c9b22SMark Johnston error = brk((void *)((intptr_t)oldbrk - 1)); 66*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno)); 67*9f9c9b22SMark Johnston newbrk = sbrk(0); 68*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno)); 69*9f9c9b22SMark Johnston ATF_REQUIRE(newbrk == oldbrk); 70*9f9c9b22SMark Johnston } 71*9f9c9b22SMark Johnston 72*9f9c9b22SMark Johnston ATF_TC(sbrk_basic); 73*9f9c9b22SMark Johnston ATF_TC_HEAD(sbrk_basic, tc) 74*9f9c9b22SMark Johnston { 75*9f9c9b22SMark Johnston atf_tc_set_md_var(tc, "descr", "Verify basic sbrk() functionality"); 76*9f9c9b22SMark Johnston } 77*9f9c9b22SMark Johnston ATF_TC_BODY(sbrk_basic, tc) 78*9f9c9b22SMark Johnston { 79*9f9c9b22SMark Johnston void *newbrk, *oldbrk; 80*9f9c9b22SMark Johnston int *p; 81*9f9c9b22SMark Johnston 82*9f9c9b22SMark Johnston oldbrk = sbrk(0); 83*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(oldbrk != (void *)-1, "sbrk: %s", strerror(errno)); 84*9f9c9b22SMark Johnston p = sbrk(sizeof(*p)); 85*9f9c9b22SMark Johnston *p = 0; 86*9f9c9b22SMark Johnston ATF_REQUIRE(oldbrk == p); 87*9f9c9b22SMark Johnston 88*9f9c9b22SMark Johnston newbrk = sbrk(-sizeof(*p)); 89*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno)); 90*9f9c9b22SMark Johnston ATF_REQUIRE(oldbrk == sbrk(0)); 91*9f9c9b22SMark Johnston 92*9f9c9b22SMark Johnston oldbrk = sbrk(PAGE_SIZE * 2 + 1); 93*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(oldbrk != (void *)-1, "sbrk: %s", strerror(errno)); 94*9f9c9b22SMark Johnston memset(oldbrk, 0, PAGE_SIZE * 2 + 1); 95*9f9c9b22SMark Johnston newbrk = sbrk(-(PAGE_SIZE * 2 + 1)); 96*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno)); 97*9f9c9b22SMark Johnston ATF_REQUIRE(sbrk(0) == oldbrk); 98*9f9c9b22SMark Johnston } 99*9f9c9b22SMark Johnston 100*9f9c9b22SMark Johnston ATF_TC(mlockfuture); 101*9f9c9b22SMark Johnston ATF_TC_HEAD(mlockfuture, tc) 102*9f9c9b22SMark Johnston { 103*9f9c9b22SMark Johnston atf_tc_set_md_var(tc, "descr", 104*9f9c9b22SMark Johnston "Verify that mlockall(MCL_FUTURE) applies to the data segment"); 105*9f9c9b22SMark Johnston } 106*9f9c9b22SMark Johnston ATF_TC_BODY(mlockfuture, tc) 107*9f9c9b22SMark Johnston { 108*9f9c9b22SMark Johnston void *oldbrk, *n, *newbrk; 109*9f9c9b22SMark Johnston int error; 110*9f9c9b22SMark Johnston char v; 111*9f9c9b22SMark Johnston 112*9f9c9b22SMark Johnston error = mlockall(MCL_FUTURE); 113*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(error == 0, 114*9f9c9b22SMark Johnston "mlockall: %s", strerror(errno)); 115*9f9c9b22SMark Johnston 116*9f9c9b22SMark Johnston /* 117*9f9c9b22SMark Johnston * Advance the break so that at least one page is added to the data 118*9f9c9b22SMark Johnston * segment. This page should be automatically faulted in to the address 119*9f9c9b22SMark Johnston * space. 120*9f9c9b22SMark Johnston */ 121*9f9c9b22SMark Johnston oldbrk = sbrk(0); 122*9f9c9b22SMark Johnston ATF_REQUIRE(oldbrk != (void *)-1); 123*9f9c9b22SMark Johnston newbrk = sbrk(PAGE_SIZE * 2); 124*9f9c9b22SMark Johnston ATF_REQUIRE(newbrk != (void *)-1); 125*9f9c9b22SMark Johnston 126*9f9c9b22SMark Johnston n = (void *)(((uintptr_t)oldbrk + PAGE_SIZE) & ~PAGE_SIZE); 127*9f9c9b22SMark Johnston v = 0; 128*9f9c9b22SMark Johnston error = mincore(n, PAGE_SIZE, &v); 129*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(error == 0, 130*9f9c9b22SMark Johnston "mincore: %s", strerror(errno)); 131*9f9c9b22SMark Johnston ATF_REQUIRE_MSG((v & MINCORE_INCORE) != 0, 132*9f9c9b22SMark Johnston "unexpected page flags %#x", v); 133*9f9c9b22SMark Johnston 134*9f9c9b22SMark Johnston error = brk(oldbrk); 135*9f9c9b22SMark Johnston ATF_REQUIRE(error == 0); 136*9f9c9b22SMark Johnston 137*9f9c9b22SMark Johnston error = munlockall(); 138*9f9c9b22SMark Johnston ATF_REQUIRE_MSG(error == 0, 139*9f9c9b22SMark Johnston "munlockall: %s", strerror(errno)); 140*9f9c9b22SMark Johnston } 141*9f9c9b22SMark Johnston 142*9f9c9b22SMark Johnston ATF_TP_ADD_TCS(tp) 143*9f9c9b22SMark Johnston { 144*9f9c9b22SMark Johnston ATF_TP_ADD_TC(tp, brk_basic); 145*9f9c9b22SMark Johnston ATF_TP_ADD_TC(tp, sbrk_basic); 146*9f9c9b22SMark Johnston ATF_TP_ADD_TC(tp, mlockfuture); 147*9f9c9b22SMark Johnston 148*9f9c9b22SMark Johnston return (atf_no_error()); 149*9f9c9b22SMark Johnston } 150