blob: 18862011c1001b04f37b867b5b61c5b3972ad3f2 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
Xiao Yang97f11832016-12-13 15:39:03 +08002 * Copyright (c) International Business Machines Corp., 2001
plars865695b2001-08-27 22:15:12 +00003 *
Xiao Yang97f11832016-12-13 15:39:03 +08004 * 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.
plars865695b2001-08-27 22:15:12 +00008 *
Xiao Yang97f11832016-12-13 15:39:03 +08009 * 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.
plars865695b2001-08-27 22:15:12 +000013 *
Xiao Yang97f11832016-12-13 15:39:03 +080014 * You should have received a copy of the GNU General Public License
15 * along with this program.
plars865695b2001-08-27 22:15:12 +000016 */
17
18/*
plars865695b2001-08-27 22:15:12 +000019 * DESCRIPTION
Xiao Yang97f11832016-12-13 15:39:03 +080020 * 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.
plars865695b2001-08-27 22:15:12 +000027 *
plars865695b2001-08-27 22:15:12 +000028 */
Xiao Yang97f11832016-12-13 15:39:03 +080029#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>
plars865695b2001-08-27 22:15:12 +000035
Xiao Yang97f11832016-12-13 15:39:03 +080036#include "tst_test.h"
Xiao Yang7d3e1662017-01-23 18:31:15 +080037#include "tst_safe_sysv_ipc.h"
Xiao Yang97f11832016-12-13 15:39:03 +080038#include "libnewipc.h"
plars865695b2001-08-27 22:15:12 +000039
Xiao Yang97f11832016-12-13 15:39:03 +080040static key_t msgkey, msgkey1;
41static int queue_id = -1;
42static struct passwd *pw;
plars865695b2001-08-27 22:15:12 +000043
Xiao Yang97f11832016-12-13 15:39:03 +080044static struct tcase {
45 int *key;
subrata_modak56207ce2009-03-23 13:35:39 +000046 int flags;
Xiao Yang97f11832016-12-13 15:39:03 +080047 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}
plars865695b2001-08-27 22:15:12 +000057};
58
Xiao Yang97f11832016-12-13 15:39:03 +080059static void verify_msgget(struct tcase *tc)
plars865695b2001-08-27 22:15:12 +000060{
Xiao Yang97f11832016-12-13 15:39:03 +080061 TEST(msgget(*tc->key, tc->flags));
plars865695b2001-08-27 22:15:12 +000062
Xiao Yang97f11832016-12-13 15:39:03 +080063 if (TEST_RETURN != -1) {
64 tst_res(TFAIL, "msgget() succeeded unexpectedly");
65 return;
66 }
plars865695b2001-08-27 22:15:12 +000067
Xiao Yang97f11832016-12-13 15:39:03 +080068 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}
plars865695b2001-08-27 22:15:12 +000075
Xiao Yang97f11832016-12-13 15:39:03 +080076static void do_test(unsigned int n)
77{
78 pid_t pid;
79 struct tcase *tc = &tcases[n];
plars865695b2001-08-27 22:15:12 +000080
Xiao Yang97f11832016-12-13 15:39:03 +080081 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);
plars865695b2001-08-27 22:15:12 +000091 }
92 }
plars865695b2001-08-27 22:15:12 +000093}
94
Xiao Yang97f11832016-12-13 15:39:03 +080095static void setup(void)
plars865695b2001-08-27 22:15:12 +000096{
Xiao Yang97f11832016-12-13 15:39:03 +080097 msgkey = GETIPCKEY();
98 msgkey1 = GETIPCKEY();
Garrett Cooper2c282152010-12-16 00:55:50 -080099
Xiao Yang7d3e1662017-01-23 18:31:15 +0800100 queue_id = SAFE_MSGGET(msgkey, IPC_CREAT | IPC_EXCL);
plars865695b2001-08-27 22:15:12 +0000101
Xiao Yang97f11832016-12-13 15:39:03 +0800102 pw = SAFE_GETPWNAM("nobody");
103}
plars865695b2001-08-27 22:15:12 +0000104
Xiao Yang97f11832016-12-13 15:39:03 +0800105static 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);
plars865695b2001-08-27 22:15:12 +0000110 }
111}
112
Xiao Yang97f11832016-12-13 15:39:03 +0800113static 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};