xref: /freebsd/lib/libc/tests/sys/brk_test.c (revision 559a218c9b257775fb249b67945fe4a05b7a6b9f)
19f9c9b22SMark Johnston /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
39f9c9b22SMark Johnston  *
49f9c9b22SMark Johnston  * Copyright (c) 2018 Mark Johnston <markj@FreeBSD.org>
59f9c9b22SMark Johnston  *
69f9c9b22SMark Johnston  * Redistribution and use in source and binary forms, with or without
79f9c9b22SMark Johnston  * modification, are permitted provided that the following conditions
89f9c9b22SMark Johnston  * are met:
99f9c9b22SMark Johnston  * 1. Redistributions of source code must retain the above copyright
109f9c9b22SMark Johnston  *    notice, this list of conditions and the following disclaimer.
119f9c9b22SMark Johnston  * 2. Redistributions in binary form must reproduce the above copyright
129f9c9b22SMark Johnston  *    notice, this list of conditions and the following disclaimer in the
139f9c9b22SMark Johnston  *    documentation and/or other materials provided with the distribution.
149f9c9b22SMark Johnston  *
159f9c9b22SMark Johnston  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
169f9c9b22SMark Johnston  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
179f9c9b22SMark Johnston  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
189f9c9b22SMark Johnston  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199f9c9b22SMark Johnston  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
209f9c9b22SMark Johnston  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
219f9c9b22SMark Johnston  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
229f9c9b22SMark Johnston  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
239f9c9b22SMark Johnston  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
249f9c9b22SMark Johnston  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
259f9c9b22SMark Johnston  * SUCH DAMAGE.
269f9c9b22SMark Johnston  */
279f9c9b22SMark Johnston 
289f9c9b22SMark Johnston #include <sys/param.h>
299f9c9b22SMark Johnston #include <sys/mman.h>
309f9c9b22SMark Johnston 
319f9c9b22SMark Johnston #include <errno.h>
329f9c9b22SMark Johnston #include <stdint.h>
339f9c9b22SMark Johnston #include <string.h>
349f9c9b22SMark Johnston #include <unistd.h>
359f9c9b22SMark Johnston 
369f9c9b22SMark Johnston #include <atf-c.h>
379f9c9b22SMark Johnston 
389f9c9b22SMark Johnston ATF_TC(brk_basic);
ATF_TC_HEAD(brk_basic,tc)399f9c9b22SMark Johnston ATF_TC_HEAD(brk_basic, tc)
409f9c9b22SMark Johnston {
419f9c9b22SMark Johnston 	atf_tc_set_md_var(tc, "descr", "Verify basic brk() functionality");
429f9c9b22SMark Johnston }
ATF_TC_BODY(brk_basic,tc)439f9c9b22SMark Johnston ATF_TC_BODY(brk_basic, tc)
449f9c9b22SMark Johnston {
459f9c9b22SMark Johnston 	void *oldbrk, *newbrk;
469f9c9b22SMark Johnston 	int error;
479f9c9b22SMark Johnston 
489f9c9b22SMark Johnston 	/* Reset the break. */
499f9c9b22SMark Johnston 	error = brk(0);
509f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno));
519f9c9b22SMark Johnston 
529f9c9b22SMark Johnston 	oldbrk = sbrk(0);
539f9c9b22SMark Johnston 	ATF_REQUIRE(oldbrk != (void *)-1);
549f9c9b22SMark Johnston 
559f9c9b22SMark Johnston 	/* Try to allocate a page. */
569f9c9b22SMark Johnston 	error = brk((void *)((intptr_t)oldbrk + PAGE_SIZE * 2));
579f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno));
589f9c9b22SMark Johnston 
599f9c9b22SMark Johnston 	/*
609f9c9b22SMark Johnston 	 * Attempt to set the break below minbrk.  This should have no effect.
619f9c9b22SMark Johnston 	 */
629f9c9b22SMark Johnston 	error = brk((void *)((intptr_t)oldbrk - 1));
639f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno));
649f9c9b22SMark Johnston 	newbrk = sbrk(0);
659f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno));
669f9c9b22SMark Johnston 	ATF_REQUIRE(newbrk == oldbrk);
679f9c9b22SMark Johnston }
689f9c9b22SMark Johnston 
699f9c9b22SMark Johnston ATF_TC(sbrk_basic);
ATF_TC_HEAD(sbrk_basic,tc)709f9c9b22SMark Johnston ATF_TC_HEAD(sbrk_basic, tc)
719f9c9b22SMark Johnston {
729f9c9b22SMark Johnston 	atf_tc_set_md_var(tc, "descr", "Verify basic sbrk() functionality");
739f9c9b22SMark Johnston }
ATF_TC_BODY(sbrk_basic,tc)749f9c9b22SMark Johnston ATF_TC_BODY(sbrk_basic, tc)
759f9c9b22SMark Johnston {
769f9c9b22SMark Johnston 	void *newbrk, *oldbrk;
779f9c9b22SMark Johnston 	int *p;
789f9c9b22SMark Johnston 
799f9c9b22SMark Johnston 	oldbrk = sbrk(0);
809f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(oldbrk != (void *)-1, "sbrk: %s", strerror(errno));
819f9c9b22SMark Johnston 	p = sbrk(sizeof(*p));
829f9c9b22SMark Johnston 	*p = 0;
839f9c9b22SMark Johnston 	ATF_REQUIRE(oldbrk == p);
849f9c9b22SMark Johnston 
859f9c9b22SMark Johnston 	newbrk = sbrk(-sizeof(*p));
869f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno));
879f9c9b22SMark Johnston 	ATF_REQUIRE(oldbrk == sbrk(0));
889f9c9b22SMark Johnston 
899f9c9b22SMark Johnston 	oldbrk = sbrk(PAGE_SIZE * 2 + 1);
909f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(oldbrk != (void *)-1, "sbrk: %s", strerror(errno));
919f9c9b22SMark Johnston 	memset(oldbrk, 0, PAGE_SIZE * 2 + 1);
929f9c9b22SMark Johnston 	newbrk = sbrk(-(PAGE_SIZE * 2 + 1));
939f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno));
949f9c9b22SMark Johnston 	ATF_REQUIRE(sbrk(0) == oldbrk);
959f9c9b22SMark Johnston }
969f9c9b22SMark Johnston 
979f9c9b22SMark Johnston ATF_TC(mlockfuture);
ATF_TC_HEAD(mlockfuture,tc)989f9c9b22SMark Johnston ATF_TC_HEAD(mlockfuture, tc)
999f9c9b22SMark Johnston {
1009f9c9b22SMark Johnston 	atf_tc_set_md_var(tc, "descr",
1019f9c9b22SMark Johnston 	    "Verify that mlockall(MCL_FUTURE) applies to the data segment");
1029f9c9b22SMark Johnston }
ATF_TC_BODY(mlockfuture,tc)1039f9c9b22SMark Johnston ATF_TC_BODY(mlockfuture, tc)
1049f9c9b22SMark Johnston {
1059f9c9b22SMark Johnston 	void *oldbrk, *n, *newbrk;
1069f9c9b22SMark Johnston 	int error;
1079f9c9b22SMark Johnston 	char v;
1089f9c9b22SMark Johnston 
1099f9c9b22SMark Johnston 	error = mlockall(MCL_FUTURE);
1109f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(error == 0,
1119f9c9b22SMark Johnston 	    "mlockall: %s", strerror(errno));
1129f9c9b22SMark Johnston 
1139f9c9b22SMark Johnston 	/*
1149f9c9b22SMark Johnston 	 * Advance the break so that at least one page is added to the data
1159f9c9b22SMark Johnston 	 * segment.  This page should be automatically faulted in to the address
1169f9c9b22SMark Johnston 	 * space.
1179f9c9b22SMark Johnston 	 */
1189f9c9b22SMark Johnston 	oldbrk = sbrk(0);
1199f9c9b22SMark Johnston 	ATF_REQUIRE(oldbrk != (void *)-1);
1209f9c9b22SMark Johnston 	newbrk = sbrk(PAGE_SIZE * 2);
1219f9c9b22SMark Johnston 	ATF_REQUIRE(newbrk != (void *)-1);
1229f9c9b22SMark Johnston 
1239f9c9b22SMark Johnston 	n = (void *)(((uintptr_t)oldbrk + PAGE_SIZE) & ~PAGE_SIZE);
1249f9c9b22SMark Johnston 	v = 0;
1259f9c9b22SMark Johnston 	error = mincore(n, PAGE_SIZE, &v);
1269f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(error == 0,
1279f9c9b22SMark Johnston 	    "mincore: %s", strerror(errno));
1289f9c9b22SMark Johnston 	ATF_REQUIRE_MSG((v & MINCORE_INCORE) != 0,
1299f9c9b22SMark Johnston 	    "unexpected page flags %#x", v);
1309f9c9b22SMark Johnston 
1319f9c9b22SMark Johnston 	error = brk(oldbrk);
1329f9c9b22SMark Johnston 	ATF_REQUIRE(error == 0);
1339f9c9b22SMark Johnston 
1349f9c9b22SMark Johnston 	error = munlockall();
1359f9c9b22SMark Johnston 	ATF_REQUIRE_MSG(error == 0,
1369f9c9b22SMark Johnston 	    "munlockall: %s", strerror(errno));
1379f9c9b22SMark Johnston }
1389f9c9b22SMark Johnston 
ATF_TP_ADD_TCS(tp)1399f9c9b22SMark Johnston ATF_TP_ADD_TCS(tp)
1409f9c9b22SMark Johnston {
1419f9c9b22SMark Johnston 	ATF_TP_ADD_TC(tp, brk_basic);
1429f9c9b22SMark Johnston 	ATF_TP_ADD_TC(tp, sbrk_basic);
1439f9c9b22SMark Johnston 	ATF_TP_ADD_TC(tp, mlockfuture);
1449f9c9b22SMark Johnston 
1459f9c9b22SMark Johnston 	return (atf_no_error());
1469f9c9b22SMark Johnston }
147