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 * DESCRIPTION 21 * Testcase to check the error conditions for mprotect(2) 22 * 23 * ALGORITHM 24 * test1: 25 * Invoke mprotect() with an address of 0. Check if error 26 * is set to ENOMEM. 27 * test2: 28 * Invoke mprotect() with an address that is not a multiple 29 * of PAGESIZE. EINVAL 30 * test3: 31 * Mmap a file with only read permission (PROT_READ). 32 * Try to set write permission (PROT_WRITE) using mprotect(2). 33 * Check that error is set to EACCES. 34 * 35 * HISTORY 36 * 07/2001 Ported by Wayne Boyer 37 * 03/2002 Paul Larson: case 1 should expect ENOMEM not EFAULT 38 */ 39 40 #include <fcntl.h> 41 #include <errno.h> 42 #include <sys/mman.h> 43 #include <stdlib.h> 44 #include <unistd.h> 45 #include "test.h" 46 #include "safe_macros.h" 47 48 char *TCID = "mprotect01"; 49 int TST_TOTAL = 3; 50 51 struct test_case { 52 void *addr; 53 int len; 54 int prot; 55 int error; 56 void (*setupfunc) (struct test_case *self); 57 }; 58 59 static void cleanup(void); 60 static void setup(void); 61 static void setup1(struct test_case *self); 62 static void setup2(struct test_case *self); 63 static void setup3(struct test_case *self); 64 65 static int fd; 66 67 struct test_case TC[] = { 68 /* Check for ENOMEM passing memory that cannot be accessed. */ 69 {NULL, 0, PROT_READ, ENOMEM, setup1}, 70 71 /* 72 * Check for EINVAL by passing a pointer which is not a 73 * multiple of PAGESIZE. 74 */ 75 {NULL, 1024, PROT_READ, EINVAL, setup2}, 76 /* 77 * Check for EACCES by trying to mark a section of memory 78 * which has been mmap'ed as read-only, as PROT_WRITE 79 */ 80 {NULL, 0, PROT_WRITE, EACCES, setup3} 81 }; 82 83 int main(int ac, char **av) 84 { 85 int lc; 86 int i; 87 88 tst_parse_opts(ac, av, NULL, NULL); 89 90 setup(); 91 92 for (lc = 0; TEST_LOOPING(lc); lc++) { 93 tst_count = 0; 94 95 for (i = 0; i < TST_TOTAL; i++) { 96 97 if (TC[i].setupfunc != NULL) 98 TC[i].setupfunc(&TC[i]); 99 100 TEST(mprotect(TC[i].addr, TC[i].len, TC[i].prot)); 101 102 if (TEST_RETURN != -1) { 103 tst_resm(TFAIL, "call succeeded unexpectedly"); 104 continue; 105 } 106 107 if (TEST_ERRNO == TC[i].error) { 108 tst_resm(TPASS, "expected failure - " 109 "errno = %d : %s", TEST_ERRNO, 110 strerror(TEST_ERRNO)); 111 } else { 112 tst_resm(TFAIL, "unexpected error - %d : %s - " 113 "expected %d", TEST_ERRNO, 114 strerror(TEST_ERRNO), TC[i].error); 115 } 116 } 117 } 118 cleanup(); 119 tst_exit(); 120 } 121 122 static void setup1(struct test_case *self) 123 { 124 self->len = getpagesize() + 1; 125 } 126 127 static void setup2(struct test_case *self) 128 { 129 self->addr = malloc(getpagesize()); 130 131 if (self->addr == NULL) 132 tst_brkm(TINFO, cleanup, "malloc failed"); 133 134 /* Ensure addr2 is not page aligned */ 135 self->addr++; 136 } 137 138 static void setup3(struct test_case *self) 139 { 140 fd = SAFE_OPEN(cleanup, "/etc/passwd", O_RDONLY); 141 142 self->len = getpagesize(); 143 144 /* 145 * mmap the PAGESIZE bytes as read only. 146 */ 147 self->addr = mmap(0, self->len, PROT_READ, MAP_SHARED, fd, 0); 148 if (self->addr == MAP_FAILED) 149 tst_brkm(TBROK, cleanup, "mmap failed"); 150 151 } 152 153 static void setup(void) 154 { 155 tst_sig(FORK, DEF_HANDLER, cleanup); 156 157 TEST_PAUSE; 158 } 159 160 static void cleanup(void) 161 { 162 close(fd); 163 } 164