Home | History | Annotate | Download | only in mmapstress
      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