1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2021 Liam R. Howlett <liam.howlett@oracle.com>
4 */
5
6 /*\
7 * [Description]
8 * Expand brk() by at least 2 pages to ensure there is a newly created VMA
9 * and not expanding the original due to multiple anon pages. mprotect() that
10 * new VMA then brk() back to the original address therefore causing a munmap of
11 * at least one full VMA.
12 */
13
14 #include <unistd.h>
15 #include <sys/mman.h>
16 #include "tst_test.h"
17
brk_down_vmas(void)18 void brk_down_vmas(void)
19 {
20 void *brk_addr = sbrk(0);
21
22 if (brk_addr == (void *) -1)
23 tst_brk(TBROK, "sbrk() failed");
24
25 unsigned long page_size = getpagesize();
26 void *addr = brk_addr + page_size;
27
28 if (brk(addr)) {
29 tst_res(TFAIL | TERRNO, "Cannot expand brk() by page size");
30 return;
31 }
32
33 addr += page_size;
34 if (brk(addr)) {
35 tst_res(TFAIL | TERRNO, "Cannot expand brk() by 2x page size");
36 return;
37 }
38
39 if (mprotect(addr - page_size, page_size, PROT_READ)) {
40 tst_res(TFAIL | TERRNO, "Cannot mprotect new VMA");
41 return;
42 }
43
44 addr += page_size;
45 if (brk(addr)) {
46 tst_res(TFAIL | TERRNO, "Cannot expand brk() after mprotect");
47 return;
48 }
49
50 if (brk(brk_addr)) {
51 tst_res(TFAIL | TERRNO, "Cannot restore brk() to start address");
52 return;
53 }
54
55 tst_res(TPASS, "munmap at least two VMAs of brk() passed");
56 }
57
58 static struct tst_test test = {
59 .test_all = brk_down_vmas,
60 };
61