1 /*
2 * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 #include <fstream>
31 #include <iostream>
32 #include "It_container_test.h"
33 using namespace std;
34
childFunc(void * arg)35 static int childFunc(void *arg)
36 {
37 int ret;
38 (void)arg;
39 char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0};
40 char mqname[] = "/testMQueue003";
41 const char msgptr[] = "childMsgs";
42 struct mq_attr attr = { 0 };
43 mqd_t mqueue;
44 attr.mq_msgsize = MQUEUE_TEST_SIZE;
45 attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG;
46
47 mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr);
48 if (mqueue == (mqd_t)-1) {
49 goto EXIT1;
50 }
51 ret = mq_send(mqueue, msgptr, strlen(msgptr), 0);
52 if (ret != 0) {
53 goto EXIT1;
54 }
55 ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL);
56 if (ret != strlen(msgptr)) {
57 goto EXIT1;
58 }
59 if (strncmp(msgrcd, msgptr, strlen(msgptr)) != 0) {
60 goto EXIT1;
61 }
62
63 EXIT1:
64 if (mqueue >= 0) {
65 ret = mq_close(mqueue);
66 if (ret != 0) {
67 return EXIT_CODE_ERRNO_1;
68 }
69 ret = mq_unlink(mqname);
70 if (ret != 0) {
71 return EXIT_CODE_ERRNO_2;
72 }
73 }
74 return EXIT_CODE_ERRNO_7;
75 }
76
ItIpcContainer002(void)77 void ItIpcContainer002(void)
78 {
79 uint32_t ret;
80 int status;
81 int exitCode;
82 mqd_t mqueue;
83 pid_t childPid;
84 int arg = CHILD_FUNC_ARG;
85 char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK,
86 -1, 0);
87 ASSERT_NE(stack, nullptr);
88 char *stackTop = stack + STACK_SIZE;
89 struct mq_attr attr = { 0 };
90 attr.mq_msgsize = MQUEUE_TEST_SIZE;
91 attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG;
92 char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0};
93 char mqname[] = "/testMQueue004";
94 const char msgptr[] = "parentMsg";
95 std::string containerType = "ipc";
96 std::string filePath;
97 int fd;
98 int parentPid;
99 std::string parentlink;
100 std::string childlink;
101
102 mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, NULL);
103 MQueueFinalizer mQueueFinalizer(mqueue, mqname);
104
105 ASSERT_NE(mqueue, (mqd_t)-1);
106
107 (void)memset_s(&attr, sizeof(attr), 0, sizeof(attr));
108 ret = mq_getattr(mqueue, &attr);
109 ASSERT_EQ(ret, 0);
110
111 attr.mq_flags |= O_NONBLOCK;
112 ret = mq_setattr(mqueue, &attr, NULL);
113 ASSERT_EQ(ret, 0);
114
115 ret = mq_getattr(mqueue, &attr);
116 ASSERT_EQ(ret, 0);
117
118 ret = mq_send(mqueue, msgptr, strlen(msgptr), 0);
119 ASSERT_EQ(ret, 0);
120
121 ret = mq_close(mqueue);
122 ASSERT_EQ(ret, 0);
123
124 ret = mq_unlink(mqname);
125 ASSERT_EQ(ret, 0);
126
127 childPid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg);
128 ASSERT_NE(childPid, -1);
129
130 parentPid = getpid();
131 parentlink = ReadlinkContainer(parentPid, containerType);
132 childlink = ReadlinkContainer(childPid, containerType);
133 filePath = GenContainerLinkPath(childPid, containerType);
134 fd = open(filePath.c_str(), O_RDONLY);
135 ASSERT_NE(fd, -1);
136
137 ret = setns(fd, CLONE_NEWIPC);
138 ASSERT_NE(ret, -1);
139
140 ret = close(fd);
141 ASSERT_NE(ret, -1);
142
143 ret = waitpid(childPid, &status, 0);
144 ASSERT_EQ(ret, childPid);
145
146 ret = WIFEXITED(status);
147 ASSERT_NE(ret, 0);
148
149 exitCode = WEXITSTATUS(status);
150 ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_7);
151 }
152