1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2004
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * NAME
22 * hugeshmat03.c
23 *
24 * DESCRIPTION
25 * hugeshmat03 - test for EACCES error
26 *
27 * ALGORITHM
28 * create a shared memory segment with root only read & write permissions
29 * fork a child process
30 * if child
31 * set the ID of the child process to that of "nobody"
32 * loop if that option was specified
33 * call shmat() using the TEST() macro
34 * check the errno value
35 * issue a PASS message if we get EACCES
36 * otherwise, the tests fails
37 * issue a FAIL message
38 * call cleanup
39 * if parent
40 * wait for child to exit
41 * remove the shared memory segment
42 *
43 * USAGE: <for command-line>
44 * hugeshmat03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
45 * where, -c n : Run n copies concurrently.
46 * -e : Turn on errno logging.
47 * -i n : Execute test n times.
48 * -I x : Execute test for x seconds.
49 * -P x : Pause for x seconds between iterations.
50 * -t : Turn on syscall timing.
51 *
52 * HISTORY
53 * 03/2001 - Written by Wayne Boyer
54 * 04/2004 - Updated by Robbie Williamson
55 *
56 * RESTRICTIONS
57 * test must be run at root
58 */
59
60 #include "hugetlb.h"
61 #include "safe_macros.h"
62 #include "mem.h"
63
64 char *TCID = "hugeshmat03";
65 int TST_TOTAL = 1;
66
67 static size_t shm_size;
68 static int shm_id_1 = -1;
69 static void *addr;
70 static uid_t ltp_uid;
71 static char *ltp_user = "nobody";
72
73 static long hugepages = 128;
74 static option_t options[] = {
75 {"s:", &sflag, &nr_opt},
76 {NULL, NULL, NULL}
77 };
78
79 static void do_child(void);
80
main(int ac,char ** av)81 int main(int ac, char **av)
82 {
83 int status;
84 pid_t pid;
85
86 tst_parse_opts(ac, av, options, NULL);
87
88 if (sflag)
89 hugepages = SAFE_STRTOL(NULL, nr_opt, 0, LONG_MAX);
90
91 setup();
92
93 switch (pid = fork()) {
94 case -1:
95 tst_brkm(TBROK | TERRNO, cleanup, "fork");
96 case 0:
97 if (setuid(ltp_uid) == -1)
98 tst_brkm(TBROK | TERRNO, cleanup, "setuid");
99 do_child();
100 tst_exit();
101 default:
102 if (waitpid(pid, &status, 0) == -1)
103 tst_brkm(TBROK | TERRNO, cleanup, "waitpid");
104 }
105 cleanup();
106 tst_exit();
107 }
108
do_child(void)109 static void do_child(void)
110 {
111 int lc;
112
113 for (lc = 0; TEST_LOOPING(lc); lc++) {
114 tst_count = 0;
115
116 addr = shmat(shm_id_1, NULL, 0);
117 if (addr != (void *)-1) {
118 tst_resm(TFAIL, "shmat succeeded unexpectedly");
119 continue;
120 }
121 if (errno == EACCES)
122 tst_resm(TPASS | TERRNO, "shmat failed as expected");
123 else
124 tst_resm(TFAIL | TERRNO, "shmat failed unexpectedly "
125 "- expect errno=EACCES, got");
126 }
127 }
128
setup(void)129 void setup(void)
130 {
131 long hpage_size;
132
133 tst_require_root();
134 check_hugepage();
135 tst_sig(FORK, DEF_HANDLER, cleanup);
136 tst_tmpdir();
137
138 orig_hugepages = get_sys_tune("nr_hugepages");
139 set_sys_tune("nr_hugepages", hugepages, 1);
140 hpage_size = read_meminfo("Hugepagesize:") * 1024;
141
142 shm_size = hpage_size * hugepages / 2;
143 update_shm_size(&shm_size);
144 shmkey = getipckey(cleanup);
145 shm_id_1 = shmget(shmkey, shm_size,
146 SHM_HUGETLB | SHM_RW | IPC_CREAT | IPC_EXCL);
147 if (shm_id_1 == -1)
148 tst_brkm(TBROK | TERRNO, cleanup, "shmget");
149
150 ltp_uid = getuserid(cleanup, ltp_user);
151
152 TEST_PAUSE;
153 }
154
cleanup(void)155 void cleanup(void)
156 {
157 rm_shm(shm_id_1);
158
159 set_sys_tune("nr_hugepages", orig_hugepages, 0);
160
161 tst_rmdir();
162 }
163