12c28215423293e443469a07ae7011135d058b671Garrett Cooper/* 20dc076565f772bb1953209fb69ea150b494aaa40robbiew * Copyright (c) 2002, Intel Corporation. All rights reserved. 30dc076565f772bb1953209fb69ea150b494aaa40robbiew * This file is licensed under the GPL license. For the full content 42c28215423293e443469a07ae7011135d058b671Garrett Cooper * of this license, see the COPYING file at the top level of this 50dc076565f772bb1953209fb69ea150b494aaa40robbiew * source tree. 60dc076565f772bb1953209fb69ea150b494aaa40robbiew * 72c28215423293e443469a07ae7011135d058b671Garrett Cooper * The munmap() function shall remove any mappings for those 82c28215423293e443469a07ae7011135d058b671Garrett Cooper * entire pages containing any part of the address space of 92c28215423293e443469a07ae7011135d058b671Garrett Cooper * the process starting at addr and continuing for len bytes. 102c28215423293e443469a07ae7011135d058b671Garrett Cooper * Further references to these pages shall result in the 112c28215423293e443469a07ae7011135d058b671Garrett Cooper * generation of a SIGSEGV signal to the process. 120dc076565f772bb1953209fb69ea150b494aaa40robbiew * 130dc076565f772bb1953209fb69ea150b494aaa40robbiew * Test Step: 140dc076565f772bb1953209fb69ea150b494aaa40robbiew * 1. map a file into memory; 150dc076565f772bb1953209fb69ea150b494aaa40robbiew * 2. unmap; 160dc076565f772bb1953209fb69ea150b494aaa40robbiew * 3. Try to reference the unmapped memory, outside the 170dc076565f772bb1953209fb69ea150b494aaa40robbiew * mapped file, test whether SIGSEGV is triggered. 180dc076565f772bb1953209fb69ea150b494aaa40robbiew */ 190dc076565f772bb1953209fb69ea150b494aaa40robbiew 200dc076565f772bb1953209fb69ea150b494aaa40robbiew#define _XOPEN_SOURCE 600 210dc076565f772bb1953209fb69ea150b494aaa40robbiew 220dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/mman.h> 230dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/types.h> 240dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/stat.h> 250dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <sys/wait.h> 2680886b520423c015b63cff03082e274147042243Garrett Cooper#include <errno.h> 270dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <fcntl.h> 2880886b520423c015b63cff03082e274147042243Garrett Cooper#include <pthread.h> 2980886b520423c015b63cff03082e274147042243Garrett Cooper#include <signal.h> 3080886b520423c015b63cff03082e274147042243Garrett Cooper#include <stdio.h> 3180886b520423c015b63cff03082e274147042243Garrett Cooper#include <stdlib.h> 320dc076565f772bb1953209fb69ea150b494aaa40robbiew#include <string.h> 3380886b520423c015b63cff03082e274147042243Garrett Cooper#include <unistd.h> 340dc076565f772bb1953209fb69ea150b494aaa40robbiew#include "posixtest.h" 352c28215423293e443469a07ae7011135d058b671Garrett Cooper 360dc076565f772bb1953209fb69ea150b494aaa40robbiew#define TNAME "munmap/1-1.c" 370dc076565f772bb1953209fb69ea150b494aaa40robbiew 380dc076565f772bb1953209fb69ea150b494aaa40robbiewvoid sigsegv_handler(int signum) 390dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 40354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Got SIGSEGV\n"); 41354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Test PASSED\n"); 42354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(PTS_PASS); 430dc076565f772bb1953209fb69ea150b494aaa40robbiew} 440dc076565f772bb1953209fb69ea150b494aaa40robbiew 454ca2bbdcd3003f3c8df4e6129e9c7b2bd1514f87Cyril Hrubisint main(void) 460dc076565f772bb1953209fb69ea150b494aaa40robbiew{ 47354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char tmpfname[256]; 48354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao long file_size; 49354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 50354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao void *pa = NULL; 51354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao void *addr = NULL; 52354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao size_t len; 53354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int flag; 54354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int fd; 55354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao off_t off = 0; 56354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int prot; 57354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 58354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int page_size; 59354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 60354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao char *ch1; 61354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 62354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao struct sigaction sa; 63354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 64354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sigfillset(&sa.sa_mask); 65354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sa.sa_handler = sigsegv_handler; 66354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao sigaction(SIGSEGV, &sa, NULL); 67354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 68354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao page_size = sysconf(_SC_PAGE_SIZE); 69354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao file_size = 2 * page_size; 70354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 71354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* We hope to map 2 pages */ 72354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao len = page_size + 1; 73354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 74354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Create tmp file */ 75354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_munmap_1_1_%d", 76354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao getpid()); 77354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unlink(tmpfname); 78354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); 79354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (fd == -1) { 80354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf(TNAME " Error at open(): %s\n", strerror(errno)); 81354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(PTS_UNRESOLVED); 82354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 83354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao unlink(tmpfname); 84354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (ftruncate(fd, file_size) == -1) { 86354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Error at ftruncate: %s\n", strerror(errno)); 87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(PTS_UNRESOLVED); 88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao flag = MAP_SHARED; 91354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao prot = PROT_READ | PROT_WRITE; 92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao pa = mmap(addr, len, prot, flag, fd, off); 93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (pa == MAP_FAILED) { 94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Test UNRESOLVED: " TNAME " Error at mmap: %s\n", 95354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao strerror(errno)); 96354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(PTS_UNRESOLVED); 97354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 99354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* ch1 is outside the mapped object, but in the mapped file */ 100354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao ch1 = pa + len + 1; 101354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao *ch1 = 'b'; 102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao close(fd); 104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao if (munmap(pa, len) == -1) { 105354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Test FAILED: " TNAME " Error at munmap: %s\n", 106354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao strerror(errno)); 107354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao exit(PTS_FAIL); 108354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao } 109354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* Try to reference the unmapped area, should trigger SIGSEGV */ 111354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao *ch1 = 'a'; 112354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao 113354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao /* If reach this point, test fail */ 114354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao printf("Test FAILED: Did not trigger SIGSEGV\n"); 115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao return PTS_FAIL; 116ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman} 117