1 /* IBM Corporation */ 2 /* 01/02/2003 Port to LTP avenkat (at) us.ibm.com */ 3 /* 06/30/2001 Port to Linux nsharoff (at) us.ibm.com */ 4 5 /* 6 * Copyright (c) International Business Machines Corp., 2003 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 * the GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 24 /* uiomove_phys_fail: 25 * Test a copyout/copyin failure in the kernel primitive uiomove_phys by 26 * reading into or writing from a mmaped regular file which lacks the 27 * needed permissions. 28 */ 29 30 #include <sys/types.h> 31 #include <sys/mman.h> 32 #include <unistd.h> 33 #include <fcntl.h> 34 #include <signal.h> 35 #include <errno.h> 36 #include <stdio.h> 37 38 extern time_t time(time_t *); 39 extern char *ctime(const time_t *); 40 extern void exit(int); 41 42 #define ERROR(M) (void)fprintf(stderr, "%s: errno = %d; " M "\n", \ 43 argv[0], errno) 44 #define CLEANERROR(M) (void)unlink(tmpname); ERROR(M) 45 #define CATCH_SIG(SIG) \ 46 if (sigaction(SIG, &sa, 0) == -1) { \ 47 ERROR("couldn't catch signal " #SIG); \ 48 exit(1); \ 49 } 50 51 static char tmpname[] = "fileXXXXXX"; 52 static int fd; 53 /***** LTP Port *****/ 54 #include "test.h" 55 #define FAILED 0 56 #define PASSED 1 57 58 int local_flag = PASSED; 59 char *TCID = "mmapstress02"; //uiomove_phys_fail 60 FILE *temp; 61 int TST_TOTAL = 1; 62 63 int anyfail(); 64 void ok_exit(); 65 /***** ** ** *****/ 66 67 /*ARGSUSED*/ static 68 void cleanup(int sig) 69 { 70 /* 71 * Don't check error codes - we could be signaled before the file is 72 * created. 73 */ 74 (void)close(fd); 75 (void)unlink(tmpname); 76 tst_rmdir(); 77 tst_exit(); 78 } 79 80 int main(int argc, char *argv[]) 81 { 82 caddr_t mmapaddr; 83 size_t pagesize = sysconf(_SC_PAGE_SIZE); 84 time_t t; 85 int i; 86 struct sigaction sa; 87 88 tst_tmpdir(); 89 if (!argc) { 90 (void)fprintf(stderr, "argc == 0\n"); 91 return 1; 92 } 93 if (argc != 1) { 94 (void)fprintf(stderr, "usage: %s\n", argv[0]); 95 return 1; 96 } 97 (void)time(&t); 98 if ((fd = mkstemp(tmpname)) == -1) { 99 ERROR("mkstemp failed"); 100 anyfail(); 101 } 102 sa.sa_handler = cleanup; 103 sa.sa_flags = 0; 104 if (sigemptyset(&sa.sa_mask)) { 105 ERROR("sigemptyset failed"); 106 anyfail(); 107 } 108 CATCH_SIG(SIGINT); 109 CATCH_SIG(SIGQUIT); 110 CATCH_SIG(SIGTERM); 111 if (sbrk(2 * pagesize - ((ulong) sbrk(0) & (pagesize - 1))) == 112 (char *)-1) { 113 CLEANERROR("couldn't round up brk"); 114 anyfail(); 115 } 116 if ((mmapaddr = sbrk(0)) == (caddr_t) - 1) { 117 CLEANERROR("couldn't find top of brk"); 118 anyfail(); 119 } 120 /* Write a page of garbage into the file, so we can mmap it without 121 * asking for PROT_WRITE. 122 */ 123 for (i = pagesize; i; i--) 124 *(mmapaddr - i) = 'a'; 125 if (write(fd, (char *)mmapaddr - pagesize, pagesize) != pagesize) { 126 CLEANERROR("write failed"); 127 anyfail(); 128 } 129 if (mmap(mmapaddr, pagesize, PROT_NONE, 130 MAP_FIXED | MAP_PRIVATE | MAP_FILE, fd, 0) != mmapaddr) { 131 CLEANERROR("couldn't mmap file"); 132 anyfail(); 133 } 134 /* 135 * Since the file is mmapped, mmreg_new and uiomove_phys handle all 136 * I/O 137 */ 138 if (lseek(fd, 0, SEEK_SET) != 0) { 139 CLEANERROR("lseek failed"); 140 anyfail(); 141 } 142 if (read(fd, (char *)mmapaddr, pagesize) != -1) { 143 CLEANERROR("read succeded"); 144 anyfail(); 145 } 146 if (errno != EFAULT) { 147 CLEANERROR("read didn't set errno = EFAULT"); 148 anyfail(); 149 } 150 if (write(fd, (char *)mmapaddr, pagesize) != -1) { 151 CLEANERROR("write succeded"); 152 anyfail(); 153 } 154 if (errno != EFAULT) { 155 CLEANERROR("write didn't set errno = EFAULT"); 156 anyfail(); 157 } 158 if (close(fd) == -1) { 159 CLEANERROR("close failed"); 160 anyfail(); 161 } 162 if (munmap(mmapaddr, pagesize) == -1) { 163 CLEANERROR("munmap failed"); 164 anyfail(); 165 } 166 if (unlink(tmpname) == -1) { 167 ERROR("unlink failed"); 168 anyfail(); 169 } 170 (void)time(&t); 171 // (void)printf("%s: Finished %s", argv[0], ctime(&t)); 172 ok_exit(); /* LTP Port */ 173 tst_exit(); 174 } 175 176 /***** LTP Port *****/ 177 void ok_exit(void) 178 { 179 tst_resm(TPASS, "Test passed\n"); 180 tst_rmdir(); 181 tst_exit(); 182 } 183 184 int anyfail(void) 185 { 186 tst_brkm(TFAIL, tst_rmdir, "Test failed"); 187 } 188 189 /***** ** ** *****/ 190