brintos

brintos / linux-shallow public Read only

0
0
Text · 5.4 KiB · d53de24 Raw
202 lines · c
1// SPDX-License-Identifier: GPL-2.02 3/*4 * Test that MAP_FIXED_NOREPLACE works.5 *6 * Copyright 2018, Jann Horn <jannh@google.com>7 * Copyright 2018, Michael Ellerman, IBM Corporation.8 */9 10#include <sys/mman.h>11#include <errno.h>12#include <stdio.h>13#include <stdlib.h>14#include <unistd.h>15#include "../kselftest.h"16 17static void dump_maps(void)18{19	char cmd[32];20 21	snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid());22	system(cmd);23}24 25static unsigned long find_base_addr(unsigned long size)26{27	void *addr;28	unsigned long flags;29 30	flags = MAP_PRIVATE | MAP_ANONYMOUS;31	addr = mmap(NULL, size, PROT_NONE, flags, -1, 0);32	if (addr == MAP_FAILED)33		ksft_exit_fail_msg("Error: couldn't map the space we need for the test\n");34 35	if (munmap(addr, size) != 0)36		ksft_exit_fail_msg("Error: munmap failed\n");37 38	return (unsigned long)addr;39}40 41int main(void)42{43	unsigned long base_addr;44	unsigned long flags, addr, size, page_size;45	char *p;46 47	ksft_print_header();48	ksft_set_plan(9);49 50	page_size = sysconf(_SC_PAGE_SIZE);51 52	/* let's find a base addr that is free before we start the tests */53	size = 5 * page_size;54	base_addr = find_base_addr(size);55 56	flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE;57 58	/* Check we can map all the areas we need below */59	addr = base_addr;60	size = 5 * page_size;61	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);62	if (p == MAP_FAILED) {63		dump_maps();64		ksft_exit_fail_msg("Error: couldn't map the space we need for the test\n");65	}66	if (munmap((void *)addr, 5 * page_size) != 0) {67		dump_maps();68		ksft_exit_fail_msg("Error: munmap failed!?\n");69	}70	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);71	ksft_test_result_pass("mmap() 5*PAGE_SIZE at base\n");72 73	addr = base_addr + page_size;74	size = 3 * page_size;75	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);76	if (p == MAP_FAILED) {77		dump_maps();78		ksft_exit_fail_msg("Error: first mmap() failed unexpectedly\n");79	}80	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);81	ksft_test_result_pass("mmap() 3*PAGE_SIZE at base+PAGE_SIZE\n");82 83	/*84	 * Exact same mapping again:85	 *   base |  free  | new86	 *     +1 | mapped | new87	 *     +2 | mapped | new88	 *     +3 | mapped | new89	 *     +4 |  free  | new90	 */91	addr = base_addr;92	size = 5 * page_size;93	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);94	if (p != MAP_FAILED) {95		dump_maps();96		ksft_exit_fail_msg("Error:1: mmap() succeeded when it shouldn't have\n");97	}98	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);99	ksft_test_result_pass("mmap() 5*PAGE_SIZE at base\n");100 101	/*102	 * Second mapping contained within first:103	 *104	 *   base |  free  |105	 *     +1 | mapped |106	 *     +2 | mapped | new107	 *     +3 | mapped |108	 *     +4 |  free  |109	 */110	addr = base_addr + (2 * page_size);111	size = page_size;112	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);113	if (p != MAP_FAILED) {114		dump_maps();115		ksft_exit_fail_msg("Error:2: mmap() succeeded when it shouldn't have\n");116	}117	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);118	ksft_test_result_pass("mmap() 2*PAGE_SIZE at base+PAGE_SIZE\n");119 120	/*121	 * Overlap end of existing mapping:122	 *   base |  free  |123	 *     +1 | mapped |124	 *     +2 | mapped |125	 *     +3 | mapped | new126	 *     +4 |  free  | new127	 */128	addr = base_addr + (3 * page_size);129	size = 2 * page_size;130	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);131	if (p != MAP_FAILED) {132		dump_maps();133		ksft_exit_fail_msg("Error:3: mmap() succeeded when it shouldn't have\n");134	}135	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);136	ksft_test_result_pass("mmap() 2*PAGE_SIZE  at base+(3*PAGE_SIZE)\n");137 138	/*139	 * Overlap start of existing mapping:140	 *   base |  free  | new141	 *     +1 | mapped | new142	 *     +2 | mapped |143	 *     +3 | mapped |144	 *     +4 |  free  |145	 */146	addr = base_addr;147	size = 2 * page_size;148	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);149	if (p != MAP_FAILED) {150		dump_maps();151		ksft_exit_fail_msg("Error:4: mmap() succeeded when it shouldn't have\n");152	}153	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);154	ksft_test_result_pass("mmap() 2*PAGE_SIZE bytes at base\n");155 156	/*157	 * Adjacent to start of existing mapping:158	 *   base |  free  | new159	 *     +1 | mapped |160	 *     +2 | mapped |161	 *     +3 | mapped |162	 *     +4 |  free  |163	 */164	addr = base_addr;165	size = page_size;166	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);167	if (p == MAP_FAILED) {168		dump_maps();169		ksft_exit_fail_msg("Error:5: mmap() failed when it shouldn't have\n");170	}171	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);172	ksft_test_result_pass("mmap() PAGE_SIZE at base\n");173 174	/*175	 * Adjacent to end of existing mapping:176	 *   base |  free  |177	 *     +1 | mapped |178	 *     +2 | mapped |179	 *     +3 | mapped |180	 *     +4 |  free  |  new181	 */182	addr = base_addr + (4 * page_size);183	size = page_size;184	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);185	if (p == MAP_FAILED) {186		dump_maps();187		ksft_exit_fail_msg("Error:6: mmap() failed when it shouldn't have\n");188	}189	ksft_print_msg("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);190	ksft_test_result_pass("mmap() PAGE_SIZE at base+(4*PAGE_SIZE)\n");191 192	addr = base_addr;193	size = 5 * page_size;194	if (munmap((void *)addr, size) != 0) {195		dump_maps();196		ksft_exit_fail_msg("Error: munmap failed!?\n");197	}198	ksft_test_result_pass("Base Address unmap() successful\n");199 200	ksft_finished();201}202