diff options
author | Doug Ledford <dledford@redhat.com> | 2012-05-31 19:26:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-31 20:49:31 -0400 |
commit | 50069a5851323ba5def0e414a21e234345016870 (patch) | |
tree | b7a6af308f2416e0da77adc7b59bfa5e84d61989 /tools | |
parent | cef0184c115e5e4e10498f6548d9526465e72478 (diff) |
selftests: add mq_open_tests
Add a directory to house POSIX message queue subsystem specific tests.
Add first test which checks the operation of mq_open() under various
corner conditions.
Signed-off-by: Doug Ledford <dledford@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Doug Ledford <dledford@redhat.com>
Cc: Joe Korty <joe.korty@ccur.com>
Cc: Amerigo Wang <amwang@redhat.com>
Cc: Serge E. Hallyn <serue@us.ibm.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/Makefile | 2 | ||||
-rw-r--r-- | tools/testing/selftests/mqueue/Makefile | 8 | ||||
-rw-r--r-- | tools/testing/selftests/mqueue/mq_open_tests.c | 492 |
3 files changed, 501 insertions, 1 deletions
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 28bc57ee757c..14972017a43e 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | TARGETS = breakpoints vm | 1 | TARGETS = breakpoints mqueue vm |
2 | 2 | ||
3 | all: | 3 | all: |
4 | for TARGET in $(TARGETS); do \ | 4 | for TARGET in $(TARGETS); do \ |
diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile new file mode 100644 index 000000000000..bd74142a173f --- /dev/null +++ b/tools/testing/selftests/mqueue/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | all: | ||
2 | gcc -O2 -lrt mq_open_tests.c -o mq_open_tests | ||
3 | |||
4 | run_tests: | ||
5 | ./mq_open_tests /test1 | ||
6 | |||
7 | clean: | ||
8 | rm -f mq_open_tests | ||
diff --git a/tools/testing/selftests/mqueue/mq_open_tests.c b/tools/testing/selftests/mqueue/mq_open_tests.c new file mode 100644 index 000000000000..711cc2923047 --- /dev/null +++ b/tools/testing/selftests/mqueue/mq_open_tests.c | |||
@@ -0,0 +1,492 @@ | |||
1 | /* | ||
2 | * This application is Copyright 2012 Red Hat, Inc. | ||
3 | * Doug Ledford <dledford@redhat.com> | ||
4 | * | ||
5 | * mq_open_tests 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, version 3. | ||
8 | * | ||
9 | * mq_open_tests 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 the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * For the full text of the license, see <http://www.gnu.org/licenses/>. | ||
15 | * | ||
16 | * mq_open_tests.c | ||
17 | * Tests the various situations that should either succeed or fail to | ||
18 | * open a posix message queue and then reports whether or not they | ||
19 | * did as they were supposed to. | ||
20 | * | ||
21 | */ | ||
22 | #include <stdio.h> | ||
23 | #include <stdlib.h> | ||
24 | #include <unistd.h> | ||
25 | #include <fcntl.h> | ||
26 | #include <string.h> | ||
27 | #include <limits.h> | ||
28 | #include <errno.h> | ||
29 | #include <sys/types.h> | ||
30 | #include <sys/time.h> | ||
31 | #include <sys/resource.h> | ||
32 | #include <sys/stat.h> | ||
33 | #include <mqueue.h> | ||
34 | |||
35 | static char *usage = | ||
36 | "Usage:\n" | ||
37 | " %s path\n" | ||
38 | "\n" | ||
39 | " path Path name of the message queue to create\n" | ||
40 | "\n" | ||
41 | " Note: this program must be run as root in order to enable all tests\n" | ||
42 | "\n"; | ||
43 | |||
44 | char *DEF_MSGS = "/proc/sys/fs/mqueue/msg_default"; | ||
45 | char *DEF_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_default"; | ||
46 | char *MAX_MSGS = "/proc/sys/fs/mqueue/msg_max"; | ||
47 | char *MAX_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_max"; | ||
48 | |||
49 | int default_settings; | ||
50 | struct rlimit saved_limits, cur_limits; | ||
51 | int saved_def_msgs, saved_def_msgsize, saved_max_msgs, saved_max_msgsize; | ||
52 | int cur_def_msgs, cur_def_msgsize, cur_max_msgs, cur_max_msgsize; | ||
53 | FILE *def_msgs, *def_msgsize, *max_msgs, *max_msgsize; | ||
54 | char *queue_path; | ||
55 | mqd_t queue = -1; | ||
56 | |||
57 | static inline void __set(FILE *stream, int value, char *err_msg); | ||
58 | void shutdown(int exit_val, char *err_cause, int line_no); | ||
59 | static inline int get(FILE *stream); | ||
60 | static inline void set(FILE *stream, int value); | ||
61 | static inline void getr(int type, struct rlimit *rlim); | ||
62 | static inline void setr(int type, struct rlimit *rlim); | ||
63 | void validate_current_settings(); | ||
64 | static inline void test_queue(struct mq_attr *attr, struct mq_attr *result); | ||
65 | static inline int test_queue_fail(struct mq_attr *attr, struct mq_attr *result); | ||
66 | |||
67 | static inline void __set(FILE *stream, int value, char *err_msg) | ||
68 | { | ||
69 | rewind(stream); | ||
70 | if (fprintf(stream, "%d", value) < 0) | ||
71 | perror(err_msg); | ||
72 | } | ||
73 | |||
74 | |||
75 | void shutdown(int exit_val, char *err_cause, int line_no) | ||
76 | { | ||
77 | static int in_shutdown = 0; | ||
78 | |||
79 | /* In case we get called recursively by a set() call below */ | ||
80 | if (in_shutdown++) | ||
81 | return; | ||
82 | |||
83 | seteuid(0); | ||
84 | |||
85 | if (queue != -1) | ||
86 | if (mq_close(queue)) | ||
87 | perror("mq_close() during shutdown"); | ||
88 | if (queue_path) | ||
89 | /* | ||
90 | * Be silent if this fails, if we cleaned up already it's | ||
91 | * expected to fail | ||
92 | */ | ||
93 | mq_unlink(queue_path); | ||
94 | if (default_settings) { | ||
95 | if (saved_def_msgs) | ||
96 | __set(def_msgs, saved_def_msgs, | ||
97 | "failed to restore saved_def_msgs"); | ||
98 | if (saved_def_msgsize) | ||
99 | __set(def_msgsize, saved_def_msgsize, | ||
100 | "failed to restore saved_def_msgsize"); | ||
101 | } | ||
102 | if (saved_max_msgs) | ||
103 | __set(max_msgs, saved_max_msgs, | ||
104 | "failed to restore saved_max_msgs"); | ||
105 | if (saved_max_msgsize) | ||
106 | __set(max_msgsize, saved_max_msgsize, | ||
107 | "failed to restore saved_max_msgsize"); | ||
108 | if (exit_val) | ||
109 | error(exit_val, errno, "%s at %d", err_cause, line_no); | ||
110 | exit(0); | ||
111 | } | ||
112 | |||
113 | static inline int get(FILE *stream) | ||
114 | { | ||
115 | int value; | ||
116 | rewind(stream); | ||
117 | if (fscanf(stream, "%d", &value) != 1) | ||
118 | shutdown(4, "Error reading /proc entry", __LINE__ - 1); | ||
119 | return value; | ||
120 | } | ||
121 | |||
122 | static inline void set(FILE *stream, int value) | ||
123 | { | ||
124 | int new_value; | ||
125 | |||
126 | rewind(stream); | ||
127 | if (fprintf(stream, "%d", value) < 0) | ||
128 | return shutdown(5, "Failed writing to /proc file", | ||
129 | __LINE__ - 1); | ||
130 | new_value = get(stream); | ||
131 | if (new_value != value) | ||
132 | return shutdown(5, "We didn't get what we wrote to /proc back", | ||
133 | __LINE__ - 1); | ||
134 | } | ||
135 | |||
136 | static inline void getr(int type, struct rlimit *rlim) | ||
137 | { | ||
138 | if (getrlimit(type, rlim)) | ||
139 | shutdown(6, "getrlimit()", __LINE__ - 1); | ||
140 | } | ||
141 | |||
142 | static inline void setr(int type, struct rlimit *rlim) | ||
143 | { | ||
144 | if (setrlimit(type, rlim)) | ||
145 | shutdown(7, "setrlimit()", __LINE__ - 1); | ||
146 | } | ||
147 | |||
148 | void validate_current_settings() | ||
149 | { | ||
150 | int rlim_needed; | ||
151 | |||
152 | if (cur_limits.rlim_cur < 4096) { | ||
153 | printf("Current rlimit value for POSIX message queue bytes is " | ||
154 | "unreasonably low,\nincreasing.\n\n"); | ||
155 | cur_limits.rlim_cur = 8192; | ||
156 | cur_limits.rlim_max = 16384; | ||
157 | setr(RLIMIT_MSGQUEUE, &cur_limits); | ||
158 | } | ||
159 | |||
160 | if (default_settings) { | ||
161 | rlim_needed = (cur_def_msgs + 1) * (cur_def_msgsize + 1 + | ||
162 | 2 * sizeof(void *)); | ||
163 | if (rlim_needed > cur_limits.rlim_cur) { | ||
164 | printf("Temporarily lowering default queue parameters " | ||
165 | "to something that will work\n" | ||
166 | "with the current rlimit values.\n\n"); | ||
167 | set(def_msgs, 10); | ||
168 | cur_def_msgs = 10; | ||
169 | set(def_msgsize, 128); | ||
170 | cur_def_msgsize = 128; | ||
171 | } | ||
172 | } else { | ||
173 | rlim_needed = (cur_max_msgs + 1) * (cur_max_msgsize + 1 + | ||
174 | 2 * sizeof(void *)); | ||
175 | if (rlim_needed > cur_limits.rlim_cur) { | ||
176 | printf("Temporarily lowering maximum queue parameters " | ||
177 | "to something that will work\n" | ||
178 | "with the current rlimit values in case this is " | ||
179 | "a kernel that ties the default\n" | ||
180 | "queue parameters to the maximum queue " | ||
181 | "parameters.\n\n"); | ||
182 | set(max_msgs, 10); | ||
183 | cur_max_msgs = 10; | ||
184 | set(max_msgsize, 128); | ||
185 | cur_max_msgsize = 128; | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | |||
190 | /* | ||
191 | * test_queue - Test opening a queue, shutdown if we fail. This should | ||
192 | * only be called in situations that should never fail. We clean up | ||
193 | * after ourselves and return the queue attributes in *result. | ||
194 | */ | ||
195 | static inline void test_queue(struct mq_attr *attr, struct mq_attr *result) | ||
196 | { | ||
197 | int flags = O_RDWR | O_EXCL | O_CREAT; | ||
198 | int perms = DEFFILEMODE; | ||
199 | |||
200 | if ((queue = mq_open(queue_path, flags, perms, attr)) == -1) | ||
201 | shutdown(1, "mq_open()", __LINE__); | ||
202 | if (mq_getattr(queue, result)) | ||
203 | shutdown(1, "mq_getattr()", __LINE__); | ||
204 | if (mq_close(queue)) | ||
205 | shutdown(1, "mq_close()", __LINE__); | ||
206 | queue = -1; | ||
207 | if (mq_unlink(queue_path)) | ||
208 | shutdown(1, "mq_unlink()", __LINE__); | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * Same as test_queue above, but failure is not fatal. | ||
213 | * Returns: | ||
214 | * 0 - Failed to create a queue | ||
215 | * 1 - Created a queue, attributes in *result | ||
216 | */ | ||
217 | static inline int test_queue_fail(struct mq_attr *attr, struct mq_attr *result) | ||
218 | { | ||
219 | int flags = O_RDWR | O_EXCL | O_CREAT; | ||
220 | int perms = DEFFILEMODE; | ||
221 | |||
222 | if ((queue = mq_open(queue_path, flags, perms, attr)) == -1) | ||
223 | return 0; | ||
224 | if (mq_getattr(queue, result)) | ||
225 | shutdown(1, "mq_getattr()", __LINE__); | ||
226 | if (mq_close(queue)) | ||
227 | shutdown(1, "mq_close()", __LINE__); | ||
228 | queue = -1; | ||
229 | if (mq_unlink(queue_path)) | ||
230 | shutdown(1, "mq_unlink()", __LINE__); | ||
231 | return 1; | ||
232 | } | ||
233 | |||
234 | int main(int argc, char *argv[]) | ||
235 | { | ||
236 | struct mq_attr attr, result; | ||
237 | |||
238 | if (argc != 2) { | ||
239 | fprintf(stderr, "Must pass a valid queue name\n\n"); | ||
240 | fprintf(stderr, usage, argv[0]); | ||
241 | exit(1); | ||
242 | } | ||
243 | |||
244 | /* | ||
245 | * Although we can create a msg queue with a non-absolute path name, | ||
246 | * unlink will fail. So, if the name doesn't start with a /, add one | ||
247 | * when we save it. | ||
248 | */ | ||
249 | if (*argv[1] == '/') | ||
250 | queue_path = strdup(argv[1]); | ||
251 | else { | ||
252 | queue_path = malloc(strlen(argv[1]) + 2); | ||
253 | if (!queue_path) { | ||
254 | perror("malloc()"); | ||
255 | exit(1); | ||
256 | } | ||
257 | queue_path[0] = '/'; | ||
258 | queue_path[1] = 0; | ||
259 | strcat(queue_path, argv[1]); | ||
260 | } | ||
261 | |||
262 | if (getuid() != 0) { | ||
263 | fprintf(stderr, "Not running as root, but almost all tests " | ||
264 | "require root in order to modify\nsystem settings. " | ||
265 | "Exiting.\n"); | ||
266 | exit(1); | ||
267 | } | ||
268 | |||
269 | /* Find out what files there are for us to make tweaks in */ | ||
270 | def_msgs = fopen(DEF_MSGS, "r+"); | ||
271 | def_msgsize = fopen(DEF_MSGSIZE, "r+"); | ||
272 | max_msgs = fopen(MAX_MSGS, "r+"); | ||
273 | max_msgsize = fopen(MAX_MSGSIZE, "r+"); | ||
274 | |||
275 | if (!max_msgs) | ||
276 | shutdown(2, "Failed to open msg_max", __LINE__); | ||
277 | if (!max_msgsize) | ||
278 | shutdown(2, "Failed to open msgsize_max", __LINE__); | ||
279 | if (def_msgs || def_msgsize) | ||
280 | default_settings = 1; | ||
281 | |||
282 | /* Load up the current system values for everything we can */ | ||
283 | getr(RLIMIT_MSGQUEUE, &saved_limits); | ||
284 | cur_limits = saved_limits; | ||
285 | if (default_settings) { | ||
286 | saved_def_msgs = cur_def_msgs = get(def_msgs); | ||
287 | saved_def_msgsize = cur_def_msgsize = get(def_msgsize); | ||
288 | } | ||
289 | saved_max_msgs = cur_max_msgs = get(max_msgs); | ||
290 | saved_max_msgsize = cur_max_msgsize = get(max_msgsize); | ||
291 | |||
292 | /* Tell the user our initial state */ | ||
293 | printf("\nInitial system state:\n"); | ||
294 | printf("\tUsing queue path:\t\t%s\n", queue_path); | ||
295 | printf("\tRLIMIT_MSGQUEUE(soft):\t\t%d\n", saved_limits.rlim_cur); | ||
296 | printf("\tRLIMIT_MSGQUEUE(hard):\t\t%d\n", saved_limits.rlim_max); | ||
297 | printf("\tMaximum Message Size:\t\t%d\n", saved_max_msgsize); | ||
298 | printf("\tMaximum Queue Size:\t\t%d\n", saved_max_msgs); | ||
299 | if (default_settings) { | ||
300 | printf("\tDefault Message Size:\t\t%d\n", saved_def_msgsize); | ||
301 | printf("\tDefault Queue Size:\t\t%d\n", saved_def_msgs); | ||
302 | } else { | ||
303 | printf("\tDefault Message Size:\t\tNot Supported\n"); | ||
304 | printf("\tDefault Queue Size:\t\tNot Supported\n"); | ||
305 | } | ||
306 | printf("\n"); | ||
307 | |||
308 | validate_current_settings(); | ||
309 | |||
310 | printf("Adjusted system state for testing:\n"); | ||
311 | printf("\tRLIMIT_MSGQUEUE(soft):\t\t%d\n", cur_limits.rlim_cur); | ||
312 | printf("\tRLIMIT_MSGQUEUE(hard):\t\t%d\n", cur_limits.rlim_max); | ||
313 | printf("\tMaximum Message Size:\t\t%d\n", cur_max_msgsize); | ||
314 | printf("\tMaximum Queue Size:\t\t%d\n", cur_max_msgs); | ||
315 | if (default_settings) { | ||
316 | printf("\tDefault Message Size:\t\t%d\n", cur_def_msgsize); | ||
317 | printf("\tDefault Queue Size:\t\t%d\n", cur_def_msgs); | ||
318 | } | ||
319 | |||
320 | printf("\n\nTest series 1, behavior when no attr struct " | ||
321 | "passed to mq_open:\n"); | ||
322 | if (!default_settings) { | ||
323 | test_queue(NULL, &result); | ||
324 | printf("Given sane system settings, mq_open without an attr " | ||
325 | "struct succeeds:\tPASS\n"); | ||
326 | if (result.mq_maxmsg != cur_max_msgs || | ||
327 | result.mq_msgsize != cur_max_msgsize) { | ||
328 | printf("Kernel does not support setting the default " | ||
329 | "mq attributes,\nbut also doesn't tie the " | ||
330 | "defaults to the maximums:\t\t\tPASS\n"); | ||
331 | } else { | ||
332 | set(max_msgs, ++cur_max_msgs); | ||
333 | set(max_msgsize, ++cur_max_msgsize); | ||
334 | test_queue(NULL, &result); | ||
335 | if (result.mq_maxmsg == cur_max_msgs && | ||
336 | result.mq_msgsize == cur_max_msgsize) | ||
337 | printf("Kernel does not support setting the " | ||
338 | "default mq attributes and\n" | ||
339 | "also ties system wide defaults to " | ||
340 | "the system wide maximums:\t\t" | ||
341 | "FAIL\n"); | ||
342 | else | ||
343 | printf("Kernel does not support setting the " | ||
344 | "default mq attributes,\n" | ||
345 | "but also doesn't tie the defaults to " | ||
346 | "the maximums:\t\t\tPASS\n"); | ||
347 | } | ||
348 | } else { | ||
349 | printf("Kernel supports setting defaults separately from " | ||
350 | "maximums:\t\tPASS\n"); | ||
351 | /* | ||
352 | * While we are here, go ahead and test that the kernel | ||
353 | * properly follows the default settings | ||
354 | */ | ||
355 | test_queue(NULL, &result); | ||
356 | printf("Given sane values, mq_open without an attr struct " | ||
357 | "succeeds:\t\tPASS\n"); | ||
358 | if (result.mq_maxmsg != cur_def_msgs || | ||
359 | result.mq_msgsize != cur_def_msgsize) | ||
360 | printf("Kernel supports setting defaults, but does " | ||
361 | "not actually honor them:\tFAIL\n\n"); | ||
362 | else { | ||
363 | set(def_msgs, ++cur_def_msgs); | ||
364 | set(def_msgsize, ++cur_def_msgsize); | ||
365 | /* In case max was the same as the default */ | ||
366 | set(max_msgs, ++cur_max_msgs); | ||
367 | set(max_msgsize, ++cur_max_msgsize); | ||
368 | test_queue(NULL, &result); | ||
369 | if (result.mq_maxmsg != cur_def_msgs || | ||
370 | result.mq_msgsize != cur_def_msgsize) | ||
371 | printf("Kernel supports setting defaults, but " | ||
372 | "does not actually honor them:\t" | ||
373 | "FAIL\n"); | ||
374 | else | ||
375 | printf("Kernel properly honors default setting " | ||
376 | "knobs:\t\t\t\tPASS\n"); | ||
377 | } | ||
378 | set(def_msgs, cur_max_msgs + 1); | ||
379 | cur_def_msgs = cur_max_msgs + 1; | ||
380 | set(def_msgsize, cur_max_msgsize + 1); | ||
381 | cur_def_msgsize = cur_max_msgsize + 1; | ||
382 | if (cur_def_msgs * (cur_def_msgsize + 2 * sizeof(void *)) >= | ||
383 | cur_limits.rlim_cur) { | ||
384 | cur_limits.rlim_cur = (cur_def_msgs + 2) * | ||
385 | (cur_def_msgsize + 2 * sizeof(void *)); | ||
386 | cur_limits.rlim_max = 2 * cur_limits.rlim_cur; | ||
387 | setr(RLIMIT_MSGQUEUE, &cur_limits); | ||
388 | } | ||
389 | if (test_queue_fail(NULL, &result)) { | ||
390 | if (result.mq_maxmsg == cur_max_msgs && | ||
391 | result.mq_msgsize == cur_max_msgsize) | ||
392 | printf("Kernel properly limits default values " | ||
393 | "to lesser of default/max:\t\tPASS\n"); | ||
394 | else | ||
395 | printf("Kernel does not properly set default " | ||
396 | "queue parameters when\ndefaults > " | ||
397 | "max:\t\t\t\t\t\t\t\tFAIL\n"); | ||
398 | } else | ||
399 | printf("Kernel fails to open mq because defaults are " | ||
400 | "greater than maximums:\tFAIL\n"); | ||
401 | set(def_msgs, --cur_def_msgs); | ||
402 | set(def_msgsize, --cur_def_msgsize); | ||
403 | cur_limits.rlim_cur = cur_limits.rlim_max = cur_def_msgs * | ||
404 | cur_def_msgsize; | ||
405 | setr(RLIMIT_MSGQUEUE, &cur_limits); | ||
406 | if (test_queue_fail(NULL, &result)) | ||
407 | printf("Kernel creates queue even though defaults " | ||
408 | "would exceed\nrlimit setting:" | ||
409 | "\t\t\t\t\t\t\t\tFAIL\n"); | ||
410 | else | ||
411 | printf("Kernel properly fails to create queue when " | ||
412 | "defaults would\nexceed rlimit:" | ||
413 | "\t\t\t\t\t\t\t\tPASS\n"); | ||
414 | } | ||
415 | |||
416 | /* | ||
417 | * Test #2 - open with an attr struct that exceeds rlimit | ||
418 | */ | ||
419 | printf("\n\nTest series 2, behavior when attr struct is " | ||
420 | "passed to mq_open:\n"); | ||
421 | cur_max_msgs = 32; | ||
422 | cur_max_msgsize = cur_limits.rlim_max >> 4; | ||
423 | set(max_msgs, cur_max_msgs); | ||
424 | set(max_msgsize, cur_max_msgsize); | ||
425 | attr.mq_maxmsg = cur_max_msgs; | ||
426 | attr.mq_msgsize = cur_max_msgsize; | ||
427 | if (test_queue_fail(&attr, &result)) | ||
428 | printf("Queue open in excess of rlimit max when euid = 0 " | ||
429 | "succeeded:\t\tFAIL\n"); | ||
430 | else | ||
431 | printf("Queue open in excess of rlimit max when euid = 0 " | ||
432 | "failed:\t\tPASS\n"); | ||
433 | attr.mq_maxmsg = cur_max_msgs + 1; | ||
434 | attr.mq_msgsize = 10; | ||
435 | if (test_queue_fail(&attr, &result)) | ||
436 | printf("Queue open with mq_maxmsg > limit when euid = 0 " | ||
437 | "succeeded:\t\tPASS\n"); | ||
438 | else | ||
439 | printf("Queue open with mq_maxmsg > limit when euid = 0 " | ||
440 | "failed:\t\tFAIL\n"); | ||
441 | attr.mq_maxmsg = 1; | ||
442 | attr.mq_msgsize = cur_max_msgsize + 1; | ||
443 | if (test_queue_fail(&attr, &result)) | ||
444 | printf("Queue open with mq_msgsize > limit when euid = 0 " | ||
445 | "succeeded:\t\tPASS\n"); | ||
446 | else | ||
447 | printf("Queue open with mq_msgsize > limit when euid = 0 " | ||
448 | "failed:\t\tFAIL\n"); | ||
449 | attr.mq_maxmsg = 65536; | ||
450 | attr.mq_msgsize = 65536; | ||
451 | if (test_queue_fail(&attr, &result)) | ||
452 | printf("Queue open with total size > 2GB when euid = 0 " | ||
453 | "succeeded:\t\tFAIL\n"); | ||
454 | else | ||
455 | printf("Queue open with total size > 2GB when euid = 0 " | ||
456 | "failed:\t\t\tPASS\n"); | ||
457 | seteuid(99); | ||
458 | attr.mq_maxmsg = cur_max_msgs; | ||
459 | attr.mq_msgsize = cur_max_msgsize; | ||
460 | if (test_queue_fail(&attr, &result)) | ||
461 | printf("Queue open in excess of rlimit max when euid = 99 " | ||
462 | "succeeded:\t\tFAIL\n"); | ||
463 | else | ||
464 | printf("Queue open in excess of rlimit max when euid = 99 " | ||
465 | "failed:\t\tPASS\n"); | ||
466 | attr.mq_maxmsg = cur_max_msgs + 1; | ||
467 | attr.mq_msgsize = 10; | ||
468 | if (test_queue_fail(&attr, &result)) | ||
469 | printf("Queue open with mq_maxmsg > limit when euid = 99 " | ||
470 | "succeeded:\t\tFAIL\n"); | ||
471 | else | ||
472 | printf("Queue open with mq_maxmsg > limit when euid = 99 " | ||
473 | "failed:\t\tPASS\n"); | ||
474 | attr.mq_maxmsg = 1; | ||
475 | attr.mq_msgsize = cur_max_msgsize + 1; | ||
476 | if (test_queue_fail(&attr, &result)) | ||
477 | printf("Queue open with mq_msgsize > limit when euid = 99 " | ||
478 | "succeeded:\t\tFAIL\n"); | ||
479 | else | ||
480 | printf("Queue open with mq_msgsize > limit when euid = 99 " | ||
481 | "failed:\t\tPASS\n"); | ||
482 | attr.mq_maxmsg = 65536; | ||
483 | attr.mq_msgsize = 65536; | ||
484 | if (test_queue_fail(&attr, &result)) | ||
485 | printf("Queue open with total size > 2GB when euid = 99 " | ||
486 | "succeeded:\t\tFAIL\n"); | ||
487 | else | ||
488 | printf("Queue open with total size > 2GB when euid = 99 " | ||
489 | "failed:\t\t\tPASS\n"); | ||
490 | |||
491 | shutdown(0,"",0); | ||
492 | } | ||