1 /* 2 * Copyright (c) 2002, Intel Corporation. All rights reserved. 3 * Copyright (c) 2012, Cyril Hrubis <chrubis (at) suse.cz> 4 * 5 * This file is licensed under the GPL license. For the full content 6 * of this license, see the COPYING file at the top level of this 7 * source tree. 8 * 9 * MPR An implementation may permit accesses other than those specified by prot; 10 * however, if the Memory Protection option is supported, the implementation 11 * shall not permit a write to succeed where PROT_WRITE has not been set or 12 * shall not permit any access where PROT_NONE alone has been set. 13 * The implementation shall support at least the following values of prot: 14 * PROT_NONE, PROT_READ, PROT_WRITE, and the bitwise-inclusive OR of PROT_READ 15 * and PROT_WRITE. 16 * 17 * Test Steps: 18 * 19 * If Memory Protection option is supported: 20 * 1. Spawn a child process. 21 * 2. The child process mmap a memory region setting prot as PROT_READ. 22 * 3. Try to write the mapped memory. 23 * 4. If the writing triger SIGSEGV, the PASS. 24 * 25 * Please refer to IEEE_1003.1-2001. 2.8.3.3 Memory Protection. 26 */ 27 28 #include <sys/mman.h> 29 #include <sys/types.h> 30 #include <sys/stat.h> 31 #include <sys/wait.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <signal.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <unistd.h> 39 #include "posixtest.h" 40 41 int main(void) 42 { 43 #ifdef _POSIX_MEMORY_PROTECTION 44 char tmpfname[256]; 45 void *pa; 46 size_t size = 1024; 47 int fd; 48 49 pid_t child; 50 int status; 51 int sig_num; 52 53 snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_6_1_%d", getpid()); 54 unlink(tmpfname); 55 fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); 56 if (fd == -1) { 57 printf("Error at open(): %s\n", strerror(errno)); 58 return PTS_UNRESOLVED; 59 } 60 unlink(tmpfname); 61 62 child = fork(); 63 64 switch (child) { 65 case 0: 66 if (ftruncate(fd, size) == -1) { 67 printf("Error at ftruncate(): %s\n", strerror(errno)); 68 return PTS_UNRESOLVED; 69 } 70 71 pa = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); 72 if (pa == MAP_FAILED) { 73 printf("Error at mmap: %s\n", strerror(errno)); 74 return PTS_FAIL; 75 } 76 77 *(char *)pa = 'b'; 78 return 0; 79 break; 80 case -1: 81 printf("Error at fork(): %s\n", strerror(errno)); 82 return PTS_UNRESOLVED; 83 break; 84 default: 85 break; 86 } 87 88 waitpid(child, &status, WUNTRACED); 89 close(fd); 90 91 if (WIFSIGNALED(status)) { 92 sig_num = WTERMSIG(status); 93 printf("Child process terminated by signal %d\n", sig_num); 94 if (sig_num == SIGSEGV) { 95 printf("Got SIGSEGV when writing to the mapped memory, " 96 "without setting PROT_WRITE\n" "Test PASSED\n"); 97 return PTS_PASS; 98 } 99 } 100 101 if (WIFEXITED(status)) { 102 if (WEXITSTATUS(status) == 0) { 103 printf 104 ("Did not got SIGSEGV when writing to the mapped memory," 105 " without setting PROT_WRITE\n" "Test FAILED\n"); 106 return PTS_FAIL; 107 } 108 } 109 110 printf("Test Unresolved\n"); 111 return PTS_UNRESOLVED; 112 #else 113 printf("Test Unsupported, _POSIX_MEMORY_PROTECTION not defined\n"); 114 return PTS_UNSUPPORTED; 115 #endif 116 } 117