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_READ 24 * - The file descriptor is open for writing. 25 * 26 * The call should fail to map the file. 27 * 28 * Expected Result: 29 * mmap() should fail returning -1 and errno should get set to EACCES. 30 * 31 * HISTORY 32 * 07/2001 Ported by Wayne Boyer 33 */ 34#include <stdio.h> 35#include <stdlib.h> 36#include <sys/types.h> 37#include <errno.h> 38#include <unistd.h> 39#include <fcntl.h> 40#include <string.h> 41#include <signal.h> 42#include <sys/stat.h> 43#include <sys/mman.h> 44 45#include "test.h" 46 47#define TEMPFILE "mmapfile" 48 49char *TCID = "mmap06"; 50int TST_TOTAL = 1; 51 52static size_t page_sz; 53static char *addr; 54static int fildes; 55 56static void setup(void); 57static void cleanup(void); 58 59int main(int ac, char **av) 60{ 61 int lc; 62 63 tst_parse_opts(ac, av, NULL, NULL); 64 65 setup(); 66 67 for (lc = 0; TEST_LOOPING(lc); lc++) { 68 69 tst_count = 0; 70 71 /* 72 * Call mmap to map the temporary file 'TEMPFILE' 73 * with read access. 74 */ 75 errno = 0; 76 addr = mmap(0, page_sz, PROT_READ, 77 MAP_FILE | MAP_SHARED, fildes, 0); 78 TEST_ERRNO = errno; 79 80 /* Check for the return value of mmap() */ 81 if (addr != MAP_FAILED) { 82 tst_resm(TFAIL | TERRNO, 83 "mmap() returned invalid value, expected: %p", 84 MAP_FAILED); 85 /* Unmap the mapped memory */ 86 if (munmap(addr, page_sz) != 0) { 87 tst_resm(TBROK, "munmap() failed"); 88 cleanup(); 89 } 90 continue; 91 } 92 if (TEST_ERRNO == EACCES) { 93 tst_resm(TPASS, "mmap failed with EACCES"); 94 } else { 95 tst_resm(TFAIL | TERRNO, 96 "mmap failed with unexpected errno"); 97 } 98 } 99 cleanup(); 100 tst_exit(); 101 102} 103 104static void setup(void) 105{ 106 char *tst_buff; 107 108 tst_sig(NOFORK, DEF_HANDLER, cleanup); 109 110 TEST_PAUSE; 111 112 page_sz = getpagesize(); 113 114 /* Allocate space for the test buffer */ 115 if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) { 116 tst_brkm(TFAIL, NULL, "calloc() failed (tst_buff)"); 117 } 118 119 /* Fill the test buffer with the known data */ 120 memset(tst_buff, 'A', page_sz); 121 122 tst_tmpdir(); 123 124 /* Creat a temporary file used for mapping */ 125 if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) { 126 free(tst_buff); 127 tst_brkm(TFAIL, cleanup, "opening %s failed", TEMPFILE); 128 } 129 130 /* Write test buffer contents into temporary file */ 131 if (write(fildes, tst_buff, page_sz) < page_sz) { 132 free(tst_buff); 133 tst_brkm(TFAIL, cleanup, "writing to %s failed", TEMPFILE); 134 } 135 136 free(tst_buff); 137} 138 139static void cleanup(void) 140{ 141 close(fildes); 142 tst_rmdir(); 143} 144