1 /* 2 * Copyright (c) International Business Machines Corp., 2001 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 /* 20 * Test Description: 21 * Call mmap() to map a file creating a mapped region with read access 22 * under the following conditions - 23 * - The prot parameter is set to PROT_WRITE 24 * - The file descriptor is open for writing. 25 * - The flags parameter has MAP_PRIVATE set. 26 * 27 * The call should fail to map the file. 28 * 29 * Expected Result: 30 * mmap() should fail returning -1 and errno should get set to EACCES. 31 * 32 * HISTORY 33 * 07/2001 Ported by Wayne Boyer 34 */ 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <sys/types.h> 38 #include <errno.h> 39 #include <unistd.h> 40 #include <fcntl.h> 41 #include <string.h> 42 #include <signal.h> 43 #include <sys/stat.h> 44 #include <sys/mman.h> 45 46 #include "test.h" 47 48 #define TEMPFILE "mmapfile" 49 50 char *TCID = "mmap07"; 51 int TST_TOTAL = 1; 52 53 static size_t page_sz; 54 static char *addr; 55 static int fildes; 56 57 static void setup(void); 58 static void cleanup(void); 59 60 int main(int ac, char **av) 61 { 62 int lc; 63 64 tst_parse_opts(ac, av, NULL, NULL); 65 66 setup(); 67 68 for (lc = 0; TEST_LOOPING(lc); lc++) { 69 70 tst_count = 0; 71 72 /* 73 * Call mmap to map the temporary file 'TEMPFILE' 74 * with write access. 75 */ 76 errno = 0; 77 addr = mmap(0, page_sz, PROT_WRITE, 78 MAP_FILE | MAP_PRIVATE, fildes, 0); 79 TEST_ERRNO = errno; 80 81 /* Check for the return value of mmap() */ 82 if (addr != MAP_FAILED) { 83 tst_resm(TFAIL | TERRNO, 84 "mmap() returned invalid value, expected: %p", 85 MAP_FAILED); 86 /* Unmap the mapped memory */ 87 if (munmap(addr, page_sz) != 0) { 88 tst_resm(TBROK, "munmap() failed"); 89 cleanup(); 90 } 91 continue; 92 } 93 if (TEST_ERRNO == EACCES) { 94 tst_resm(TPASS, "mmap failed with EACCES"); 95 } else { 96 tst_resm(TFAIL | TERRNO, 97 "mmap failed with unexpected errno"); 98 } 99 100 } 101 cleanup(); 102 tst_exit(); 103 104 } 105 106 static void setup(void) 107 { 108 char *tst_buff; 109 110 tst_sig(NOFORK, DEF_HANDLER, cleanup); 111 112 TEST_PAUSE; 113 114 page_sz = getpagesize(); 115 116 /* Allocate space for the test buffer */ 117 if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) { 118 tst_brkm(TFAIL, NULL, 119 "calloc() failed to allocate space for tst_buff"); 120 } 121 122 /* Fill the test buffer with the known data */ 123 memset(tst_buff, 'A', page_sz); 124 125 tst_tmpdir(); 126 127 /* Creat a temporary file used for mapping */ 128 if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) { 129 free(tst_buff); 130 tst_brkm(TFAIL, cleanup, "open() on %s failed", TEMPFILE); 131 } 132 133 /* Write test buffer contents into temporary file */ 134 if (write(fildes, tst_buff, page_sz) < page_sz) { 135 free(tst_buff); 136 tst_brkm(TFAIL, cleanup, "writing to %s failed", TEMPFILE); 137 } 138 139 free(tst_buff); 140 } 141 142 static void cleanup(void) 143 { 144 close(fildes); 145 tst_rmdir(); 146 } 147