cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

map_fixed_noreplace.c (5230B)


      1// SPDX-License-Identifier: GPL-2.0
      2
      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
     16#ifndef MAP_FIXED_NOREPLACE
     17#define MAP_FIXED_NOREPLACE 0x100000
     18#endif
     19
     20static void dump_maps(void)
     21{
     22	char cmd[32];
     23
     24	snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid());
     25	system(cmd);
     26}
     27
     28static unsigned long find_base_addr(unsigned long size)
     29{
     30	void *addr;
     31	unsigned long flags;
     32
     33	flags = MAP_PRIVATE | MAP_ANONYMOUS;
     34	addr = mmap(NULL, size, PROT_NONE, flags, -1, 0);
     35	if (addr == MAP_FAILED) {
     36		printf("Error: couldn't map the space we need for the test\n");
     37		return 0;
     38	}
     39
     40	if (munmap(addr, size) != 0) {
     41		printf("Error: couldn't map the space we need for the test\n");
     42		return 0;
     43	}
     44	return (unsigned long)addr;
     45}
     46
     47int main(void)
     48{
     49	unsigned long base_addr;
     50	unsigned long flags, addr, size, page_size;
     51	char *p;
     52
     53	page_size = sysconf(_SC_PAGE_SIZE);
     54
     55	//let's find a base addr that is free before we start the tests
     56	size = 5 * page_size;
     57	base_addr = find_base_addr(size);
     58	if (!base_addr) {
     59		printf("Error: couldn't map the space we need for the test\n");
     60		return 1;
     61	}
     62
     63	flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE;
     64
     65	// Check we can map all the areas we need below
     66	errno = 0;
     67	addr = base_addr;
     68	size = 5 * page_size;
     69	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
     70
     71	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
     72
     73	if (p == MAP_FAILED) {
     74		dump_maps();
     75		printf("Error: couldn't map the space we need for the test\n");
     76		return 1;
     77	}
     78
     79	errno = 0;
     80	if (munmap((void *)addr, 5 * page_size) != 0) {
     81		dump_maps();
     82		printf("Error: munmap failed!?\n");
     83		return 1;
     84	}
     85	printf("unmap() successful\n");
     86
     87	errno = 0;
     88	addr = base_addr + page_size;
     89	size = 3 * page_size;
     90	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
     91	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
     92
     93	if (p == MAP_FAILED) {
     94		dump_maps();
     95		printf("Error: first mmap() failed unexpectedly\n");
     96		return 1;
     97	}
     98
     99	/*
    100	 * Exact same mapping again:
    101	 *   base |  free  | new
    102	 *     +1 | mapped | new
    103	 *     +2 | mapped | new
    104	 *     +3 | mapped | new
    105	 *     +4 |  free  | new
    106	 */
    107	errno = 0;
    108	addr = base_addr;
    109	size = 5 * page_size;
    110	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
    111	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
    112
    113	if (p != MAP_FAILED) {
    114		dump_maps();
    115		printf("Error:1: mmap() succeeded when it shouldn't have\n");
    116		return 1;
    117	}
    118
    119	/*
    120	 * Second mapping contained within first:
    121	 *
    122	 *   base |  free  |
    123	 *     +1 | mapped |
    124	 *     +2 | mapped | new
    125	 *     +3 | mapped |
    126	 *     +4 |  free  |
    127	 */
    128	errno = 0;
    129	addr = base_addr + (2 * page_size);
    130	size = page_size;
    131	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
    132	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
    133
    134	if (p != MAP_FAILED) {
    135		dump_maps();
    136		printf("Error:2: mmap() succeeded when it shouldn't have\n");
    137		return 1;
    138	}
    139
    140	/*
    141	 * Overlap end of existing mapping:
    142	 *   base |  free  |
    143	 *     +1 | mapped |
    144	 *     +2 | mapped |
    145	 *     +3 | mapped | new
    146	 *     +4 |  free  | new
    147	 */
    148	errno = 0;
    149	addr = base_addr + (3 * page_size);
    150	size = 2 * page_size;
    151	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
    152	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
    153
    154	if (p != MAP_FAILED) {
    155		dump_maps();
    156		printf("Error:3: mmap() succeeded when it shouldn't have\n");
    157		return 1;
    158	}
    159
    160	/*
    161	 * Overlap start of existing mapping:
    162	 *   base |  free  | new
    163	 *     +1 | mapped | new
    164	 *     +2 | mapped |
    165	 *     +3 | mapped |
    166	 *     +4 |  free  |
    167	 */
    168	errno = 0;
    169	addr = base_addr;
    170	size = 2 * page_size;
    171	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
    172	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
    173
    174	if (p != MAP_FAILED) {
    175		dump_maps();
    176		printf("Error:4: mmap() succeeded when it shouldn't have\n");
    177		return 1;
    178	}
    179
    180	/*
    181	 * Adjacent to start of existing mapping:
    182	 *   base |  free  | new
    183	 *     +1 | mapped |
    184	 *     +2 | mapped |
    185	 *     +3 | mapped |
    186	 *     +4 |  free  |
    187	 */
    188	errno = 0;
    189	addr = base_addr;
    190	size = page_size;
    191	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
    192	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
    193
    194	if (p == MAP_FAILED) {
    195		dump_maps();
    196		printf("Error:5: mmap() failed when it shouldn't have\n");
    197		return 1;
    198	}
    199
    200	/*
    201	 * Adjacent to end of existing mapping:
    202	 *   base |  free  |
    203	 *     +1 | mapped |
    204	 *     +2 | mapped |
    205	 *     +3 | mapped |
    206	 *     +4 |  free  |  new
    207	 */
    208	errno = 0;
    209	addr = base_addr + (4 * page_size);
    210	size = page_size;
    211	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
    212	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);
    213
    214	if (p == MAP_FAILED) {
    215		dump_maps();
    216		printf("Error:6: mmap() failed when it shouldn't have\n");
    217		return 1;
    218	}
    219
    220	addr = base_addr;
    221	size = 5 * page_size;
    222	if (munmap((void *)addr, size) != 0) {
    223		dump_maps();
    224		printf("Error: munmap failed!?\n");
    225		return 1;
    226	}
    227	printf("unmap() successful\n");
    228
    229	printf("OK\n");
    230	return 0;
    231}