blob: 8e50337c2a0d58e8b472fda7cfd9111c35c0dc98 [file] [log] [blame]
robbiew84457092003-01-10 17:48:12 +00001/* IBM Corporation */
2/* 01/02/2003 Port to LTP avenkat@us.ibm.com */
3/* 06/30/2001 Port to Linux nsharoff@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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
robbiew84457092003-01-10 17:48:12 +000022 */
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
Wanlong Gao354ebb42012-12-07 10:10:04 +080038extern time_t time(time_t *);
39extern char *ctime(const time_t *);
40extern void exit(int);
robbiew84457092003-01-10 17:48:12 +000041
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
51static char tmpname[] = "fileXXXXXX";
Wanlong Gao354ebb42012-12-07 10:10:04 +080052static int fd;
robbiew84457092003-01-10 17:48:12 +000053/***** LTP Port *****/
54#include "test.h"
robbiew84457092003-01-10 17:48:12 +000055#define FAILED 0
56#define PASSED 1
57
58int local_flag = PASSED;
Wanlong Gao354ebb42012-12-07 10:10:04 +080059char *TCID = "mmapstress02"; //uiomove_phys_fail
robbiew84457092003-01-10 17:48:12 +000060FILE *temp;
61int TST_TOTAL = 1;
robbiew84457092003-01-10 17:48:12 +000062
63int anyfail();
64void ok_exit();
65/***** ** ** *****/
66
Wanlong Gao354ebb42012-12-07 10:10:04 +080067 /*ARGSUSED*/ static
68void cleanup(int sig)
robbiew84457092003-01-10 17:48:12 +000069{
Wanlong Gao354ebb42012-12-07 10:10:04 +080070 /*
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);
robbiew84457092003-01-10 17:48:12 +000076 tst_rmdir();
Wanlong Gao354ebb42012-12-07 10:10:04 +080077 tst_exit();
robbiew84457092003-01-10 17:48:12 +000078}
79
Wanlong Gao354ebb42012-12-07 10:10:04 +080080int 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;
robbiew84457092003-01-10 17:48:12 +000087
subrata_modakbdbaec52009-02-26 12:14:51 +000088 tst_tmpdir();
robbiew84457092003-01-10 17:48:12 +000089 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);
subrata_modakacb84492009-10-26 14:36:28 +000098 if ((fd = mkstemp(tmpname)) == -1) {
robbiewe93a3242005-08-31 20:27:12 +000099 ERROR("mkstemp failed");
robbiew84457092003-01-10 17:48:12 +0000100 anyfail();
101 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800102 sa.sa_handler = cleanup;
103 sa.sa_flags = 0;
104 if (sigemptyset(&sa.sa_mask)) {
105 ERROR("sigemptyset failed");
robbiew84457092003-01-10 17:48:12 +0000106 anyfail();
Wanlong Gao354ebb42012-12-07 10:10:04 +0800107 }
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) {
robbiew84457092003-01-10 17:48:12 +0000113 CLEANERROR("couldn't round up brk");
114 anyfail();
115 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800116 if ((mmapaddr = sbrk(0)) == (caddr_t) - 1) {
robbiew84457092003-01-10 17:48:12 +0000117 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--)
Wanlong Gao354ebb42012-12-07 10:10:04 +0800124 *(mmapaddr - i) = 'a';
125 if (write(fd, (char *)mmapaddr - pagesize, pagesize) != pagesize) {
robbiew84457092003-01-10 17:48:12 +0000126 CLEANERROR("write failed");
127 anyfail();
128 }
129 if (mmap(mmapaddr, pagesize, PROT_NONE,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800130 MAP_FIXED | MAP_PRIVATE | MAP_FILE, fd, 0) != mmapaddr) {
robbiew84457092003-01-10 17:48:12 +0000131 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 }
Subrata Modak76a720a2010-07-03 21:08:18 +0530162 if (munmap(mmapaddr, pagesize) == -1) {
163 CLEANERROR("munmap failed");
164 anyfail();
165 }
robbiew84457092003-01-10 17:48:12 +0000166 if (unlink(tmpname) == -1) {
167 ERROR("unlink failed");
168 anyfail();
169 }
170 (void)time(&t);
Wanlong Gao354ebb42012-12-07 10:10:04 +0800171// (void)printf("%s: Finished %s", argv[0], ctime(&t));
172 ok_exit(); /* LTP Port */
Garrett Cooper2c282152010-12-16 00:55:50 -0800173 tst_exit();
robbiew84457092003-01-10 17:48:12 +0000174}
175
176/***** LTP Port *****/
177void ok_exit()
178{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800179 tst_resm(TPASS, "Test passed\n");
180 tst_rmdir();
robbiew84457092003-01-10 17:48:12 +0000181 tst_exit();
182}
183
robbiew84457092003-01-10 17:48:12 +0000184int anyfail()
185{
Cyril Hrubis9fa8ad02014-12-16 13:20:49 +0100186 tst_brkm(TFAIL, tst_rmdir, "Test failed");
robbiew84457092003-01-10 17:48:12 +0000187}
188
Chris Dearmanec6edca2012-10-17 19:54:01 -0700189/***** ** ** *****/