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/exec access
22 * under the following conditions -
23 * - The prot parameter is set to PROT_READ|PROT_EXEC
24 * - The file descriptor is open for read
25 * - The file being mapped has read and execute permission bit set.
26 * - The minimum file permissions should be 0555.
27 *
28 * The call should succeed to map the file creating mapped memory with the
29 * required attributes.
30 *
31 * Expected Result:
32 * mmap() should succeed returning the address of the mapped region,
33 * and the mapped region should contain the contents of the mapped file.
34 *
35 * HISTORY
36 * 07/2001 Ported by Wayne Boyer
37 */
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <sys/types.h>
42 #include <errno.h>
43 #include <unistd.h>
44 #include <fcntl.h>
45 #include <string.h>
46 #include <signal.h>
47 #include <sys/stat.h>
48 #include <sys/mman.h>
49
50 #include "test.h"
51
52 #define TEMPFILE "mmapfile"
53
54 char *TCID = "mmap04";
55 int TST_TOTAL = 1;
56
57 static size_t page_sz;
58 static char *addr;
59 static char *dummy;
60 static int fildes;
61
62 static void setup(void);
63 static void cleanup(void);
64
main(int ac,char ** av)65 int main(int ac, char **av)
66 {
67 int lc;
68
69 tst_parse_opts(ac, av, NULL, NULL);
70
71 setup();
72
73 for (lc = 0; TEST_LOOPING(lc); lc++) {
74
75 tst_count = 0;
76
77 /*
78 * Call mmap to map the temporary file 'TEMPFILE'
79 * with read and execute access.
80 */
81 errno = 0;
82 addr = mmap(0, page_sz, PROT_READ | PROT_EXEC,
83 MAP_FILE | MAP_SHARED, fildes, 0);
84
85 /* Check for the return value of mmap() */
86 if (addr == MAP_FAILED) {
87 tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE);
88 continue;
89 }
90
91 /*
92 * Read the file contents into the dummy
93 * variable.
94 */
95 if (read(fildes, dummy, page_sz) < 0) {
96 tst_brkm(TFAIL, cleanup, "reading %s failed",
97 TEMPFILE);
98 }
99
100 /*
101 * Check whether the mapped memory region
102 * has the file contents.
103 */
104 if (memcmp(dummy, addr, page_sz)) {
105 tst_resm(TFAIL,
106 "mapped memory region contains invalid "
107 "data");
108 } else {
109 tst_resm(TPASS,
110 "Functionality of mmap() successful");
111 }
112
113 /* Clean up things in case we are looping. */
114 /* Unmap the mapped memory */
115 if (munmap(addr, page_sz) != 0) {
116 tst_brkm(TFAIL, cleanup, "munmapping failed");
117 }
118 }
119
120 cleanup();
121 tst_exit();
122 }
123
setup(void)124 static void setup(void)
125 {
126 char *tst_buff;
127
128 tst_sig(NOFORK, DEF_HANDLER, cleanup);
129
130 TEST_PAUSE;
131
132 page_sz = getpagesize();
133
134 if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) {
135 tst_brkm(TFAIL, NULL, "calloc failed (tst_buff)");
136 }
137
138 /* Fill the test buffer with the known data */
139 memset(tst_buff, 'A', page_sz);
140
141 tst_tmpdir();
142
143 /* Creat a temporary file used for mapping */
144 if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
145 free(tst_buff);
146 tst_brkm(TFAIL, cleanup, "opening %s failed", TEMPFILE);
147 }
148
149 /* Write test buffer contents into temporary file */
150 if (write(fildes, tst_buff, page_sz) < page_sz) {
151 free(tst_buff);
152 tst_brkm(TFAIL, cleanup, "writing to %s failed", TEMPFILE);
153 }
154
155 /* Free the memory allocated for test buffer */
156 free(tst_buff);
157
158 /* Make sure proper permissions set on file */
159 if (fchmod(fildes, 0555) < 0) {
160 tst_brkm(TFAIL, cleanup, "fchmod of %s failed", TEMPFILE);
161 }
162
163 /* Close the temporary file opened for write */
164 if (close(fildes) < 0) {
165 tst_brkm(TFAIL, cleanup, "closing %s failed", TEMPFILE);
166 }
167
168 /* Allocate and initialize dummy string of system page size bytes */
169 if ((dummy = calloc(page_sz, sizeof(char))) == NULL) {
170 tst_brkm(TFAIL, cleanup, "calloc failed (dummy)");
171 }
172
173 /* Open the temporary file again for reading */
174 if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
175 tst_brkm(TFAIL, cleanup,
176 "opening %s read-only failed", TEMPFILE);
177 }
178 }
179
cleanup(void)180 static void cleanup(void)
181 {
182 close(fildes);
183 free(dummy);
184 tst_rmdir();
185 }
186