• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd
4  *          Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>,
5  *		       Yumiko Sugita <yumiko.sugita.yf@hitachi.com>,
6  *		       Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp>
7  * Copyright (c) 2016 Linux Test Project
8  */
9 
10 #include <errno.h>
11 #include <pwd.h>
12 #include <mqueue.h>
13 
14 #include "tst_test.h"
15 #include "tst_safe_posix_ipc.h"
16 
17 #define QUEUE_NAME	"/test_mqueue"
18 
19 static uid_t euid;
20 static struct passwd *pw;
21 
22 struct test_case {
23 	int as_nobody;
24 	char *qname;
25 	int ret;
26 	int err;
27 };
28 
29 static struct test_case tcase[] = {
30 	{
31 		.qname = QUEUE_NAME,
32 		.ret = 0,
33 		.err = 0,
34 	},
35 	{
36 		.as_nobody = 1,
37 		.qname = QUEUE_NAME,
38 		.ret = -1,
39 		.err = EACCES,
40 	},
41 	{
42 		.qname = "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
43 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
44 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
45 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
46 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
47 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
48 			"aaaaaaaaaaaaaaa",
49 		.ret = -1,
50 		.err = ENOENT,
51 	},
52 	{
53 		.qname = "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
54 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
55 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
56 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
57 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
58 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
59 			"aaaaaaaaaaaaaaaa",
60 		.ret = -1,
61 		.err = ENAMETOOLONG,
62 	},
63 };
64 
setup(void)65 void setup(void)
66 {
67 	euid = geteuid();
68 	pw = SAFE_GETPWNAM("nobody");
69 }
70 
do_test(unsigned int i)71 static void do_test(unsigned int i)
72 {
73 	struct test_case *tc = &tcase[i];
74 	mqd_t fd;
75 
76 	tst_res(TINFO, "queue name %s", tc->qname);
77 
78 	/*
79 	 * When test ended with SIGTERM etc, mq descriptor is left remains.
80 	 * So we delete it first.
81 	 */
82 	mq_unlink(QUEUE_NAME);
83 
84 	/* prepare */
85 	fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU, NULL);
86 
87 	if (tc->as_nobody && seteuid(pw->pw_uid)) {
88 		tst_res(TBROK | TERRNO, "seteuid failed");
89 		goto EXIT;
90 	}
91 
92 	/* test */
93 	TEST(mq_unlink(tc->qname));
94 	if (TST_ERR != tc->err || TST_RET != tc->ret) {
95 		tst_res(TFAIL | TTERRNO, "mq_unlink returned %ld, expected %d,"
96 			" expected errno %s (%d)", TST_RET,
97 			tc->ret, tst_strerrno(tc->err), tc->err);
98 	} else {
99 		tst_res(TPASS | TTERRNO, "mq_unlink returned %ld", TST_RET);
100 	}
101 
102 EXIT:
103 	/* cleanup */
104 	if (tc->as_nobody && seteuid(euid) == -1)
105 		tst_res(TWARN | TERRNO, "seteuid back to %d failed", euid);
106 
107 	if (fd > 0 && close(fd))
108 		tst_res(TWARN | TERRNO, "close(fd) failed");
109 
110 	mq_unlink(QUEUE_NAME);
111 }
112 
113 static struct tst_test test = {
114 	.tcnt = ARRAY_SIZE(tcase),
115 	.test = do_test,
116 	.needs_root = 1,
117 	.setup = setup,
118 };
119