plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 1 | /* |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 2 | * Copyright (c) International Business Machines Corp., 2001 |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 3 | * |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 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. |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 8 | * |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 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. |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 13 | * |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 14 | * You should have received a copy of the GNU General Public License |
| 15 | * along with this program. |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 16 | */ |
| 17 | |
| 18 | /* |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 19 | * DESCRIPTION |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 20 | * 1) msgget(2) fails if a message queue exists for key and msgflg |
| 21 | * specified both IPC_CREAT and IPC_EXCL. |
| 22 | * 2) msgget(2) fails if no message queue exists for key and msgflg |
| 23 | * did not specify IPC_CREAT. |
| 24 | * 3) msgget(2) fails if a message queue exists for key, but the |
| 25 | * calling process does not have permission to access the queue, |
| 26 | * and does not have the CAP_IPC_OWNER capability. |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 27 | * |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 28 | */ |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 29 | #include <errno.h> |
| 30 | #include <stdlib.h> |
| 31 | #include <sys/types.h> |
| 32 | #include <sys/ipc.h> |
| 33 | #include <sys/msg.h> |
| 34 | #include <pwd.h> |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 35 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 36 | #include "tst_test.h" |
Xiao Yang | 7d3e166 | 2017-01-23 18:31:15 +0800 | [diff] [blame^] | 37 | #include "tst_safe_sysv_ipc.h" |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 38 | #include "libnewipc.h" |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 39 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 40 | static key_t msgkey, msgkey1; |
| 41 | static int queue_id = -1; |
| 42 | static struct passwd *pw; |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 43 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 44 | static struct tcase { |
| 45 | int *key; |
subrata_modak | 56207ce | 2009-03-23 13:35:39 +0000 | [diff] [blame] | 46 | int flags; |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 47 | int exp_err; |
| 48 | /*1: nobody expected 0: root expected */ |
| 49 | int exp_user; |
| 50 | } tcases[] = { |
| 51 | {&msgkey, IPC_CREAT | IPC_EXCL, EEXIST, 0}, |
| 52 | {&msgkey1, IPC_PRIVATE, ENOENT, 0}, |
| 53 | {&msgkey1, IPC_EXCL, ENOENT, 0}, |
| 54 | {&msgkey, MSG_RD, EACCES, 1}, |
| 55 | {&msgkey, MSG_WR, EACCES, 1}, |
| 56 | {&msgkey, MSG_RW, EACCES, 1} |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 57 | }; |
| 58 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 59 | static void verify_msgget(struct tcase *tc) |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 60 | { |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 61 | TEST(msgget(*tc->key, tc->flags)); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 62 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 63 | if (TEST_RETURN != -1) { |
| 64 | tst_res(TFAIL, "msgget() succeeded unexpectedly"); |
| 65 | return; |
| 66 | } |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 67 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 68 | if (TEST_ERRNO == tc->exp_err) { |
| 69 | tst_res(TPASS | TTERRNO, "msgget() failed as expected"); |
| 70 | } else { |
| 71 | tst_res(TFAIL | TTERRNO, "msgget() failed unexpectedly," |
| 72 | " expected %s", tst_strerrno(tc->exp_err)); |
| 73 | } |
| 74 | } |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 75 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 76 | static void do_test(unsigned int n) |
| 77 | { |
| 78 | pid_t pid; |
| 79 | struct tcase *tc = &tcases[n]; |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 80 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 81 | if (tc->exp_user == 0) { |
| 82 | verify_msgget(tc); |
| 83 | } else { |
| 84 | pid = SAFE_FORK(); |
| 85 | if (pid) { |
| 86 | tst_reap_children(); |
| 87 | } else { |
| 88 | SAFE_SETUID(pw->pw_uid); |
| 89 | verify_msgget(tc); |
| 90 | exit(0); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 91 | } |
| 92 | } |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 93 | } |
| 94 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 95 | static void setup(void) |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 96 | { |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 97 | msgkey = GETIPCKEY(); |
| 98 | msgkey1 = GETIPCKEY(); |
Garrett Cooper | 2c28215 | 2010-12-16 00:55:50 -0800 | [diff] [blame] | 99 | |
Xiao Yang | 7d3e166 | 2017-01-23 18:31:15 +0800 | [diff] [blame^] | 100 | queue_id = SAFE_MSGGET(msgkey, IPC_CREAT | IPC_EXCL); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 101 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 102 | pw = SAFE_GETPWNAM("nobody"); |
| 103 | } |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 104 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 105 | static void cleanup(void) |
| 106 | { |
| 107 | if (queue_id != -1 && msgctl(queue_id, IPC_RMID, NULL)) { |
| 108 | tst_res(TWARN | TERRNO, "failed to delete message queue %i", |
| 109 | queue_id); |
plars | 865695b | 2001-08-27 22:15:12 +0000 | [diff] [blame] | 110 | } |
| 111 | } |
| 112 | |
Xiao Yang | 97f1183 | 2016-12-13 15:39:03 +0800 | [diff] [blame] | 113 | static struct tst_test test = { |
| 114 | .tid = "msgget02", |
| 115 | .needs_tmpdir = 1, |
| 116 | .needs_root = 1, |
| 117 | .forks_child = 1, |
| 118 | .tcnt = ARRAY_SIZE(tcases), |
| 119 | .setup = setup, |
| 120 | .cleanup = cleanup, |
| 121 | .test = do_test |
| 122 | }; |