• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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[] = "/testMQueue005";
41     const char msgptr[] = "childMsg";
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 
IpcContainerUnshare(void)77 static void IpcContainerUnshare(void)
78 {
79     int status, exitCode, ret;
80     int arg = CHILD_FUNC_ARG;
81     char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, CLONE_STACK_MMAP_FLAG, -1, 0);
82     ASSERT_NE(stack, nullptr);
83     char *stackTop = stack + STACK_SIZE;
84     struct mq_attr attr = { 0 };
85     attr.mq_msgsize = MQUEUE_TEST_SIZE;
86     attr.mq_maxmsg = MQUEUE_TEST_MAX_MSG;
87     struct sigevent notification;
88     notification.sigev_notify = 5; /* 5: test data */
89     char msgrcd[MQUEUE_STANDARD_NAME_LENGTH] = {0};
90     char mqname[] = "/testMQueue006";
91     const char msgptr[] = "parentMsg";
92 
93     ret = unshare(CLONE_NEWIPC);
94     ASSERT_EQ(ret, 0);
95 
96     mqd_t mqueue = mq_open(mqname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR, &attr);
97     MQueueFinalizer mQueueFinalizer(mqueue, mqname);
98 
99     ASSERT_NE(mqueue, (mqd_t)-1);
100 
101     ret = mq_notify(mqueue, &notification);
102     ASSERT_EQ(ret, -1);
103     ASSERT_EQ(errno, EINVAL);
104 
105     notification.sigev_notify = SIGEV_THREAD;
106     ret = mq_notify(mqueue, &notification);
107     ASSERT_EQ(ret, -1);
108     ASSERT_EQ(errno, ENOTSUP);
109 
110     notification.sigev_notify = SIGEV_NONE;
111 
112     ret = mq_notify(-1, &notification);
113     ASSERT_EQ(ret, -1);
114     ASSERT_EQ(errno, EBADF);
115 
116     ret = mq_notify(mqueue, &notification);
117     ASSERT_EQ(ret, 0);
118 
119     (void)memset_s(&attr, sizeof(attr), 0, sizeof(attr));
120     ret = mq_getattr(mqueue, &attr);
121     ASSERT_EQ(ret, 0);
122 
123     attr.mq_flags |= O_NONBLOCK;
124     ret = mq_setattr(mqueue, &attr, NULL);
125     ASSERT_EQ(ret, 0);
126 
127     ret = mq_getattr(mqueue, &attr);
128     ASSERT_EQ(ret, 0);
129 
130     ret = mq_send(mqueue, msgptr, strlen(msgptr), 0);
131     ASSERT_EQ(ret, 0);
132 
133     pid_t pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg);
134     ASSERT_NE(pid, -1);
135 
136     ret = waitpid(pid, &status, 0);
137     ASSERT_EQ(ret, pid);
138 
139     ret = WIFEXITED(status);
140     ASSERT_NE(pid, 0);
141 
142     exitCode = WEXITSTATUS(status);
143     ASSERT_EQ(exitCode, EXIT_CODE_ERRNO_7);
144 
145     ret = mq_notify(mqueue, nullptr);
146     ASSERT_EQ(ret, 0);
147 
148     ret = mq_receive(mqueue, msgrcd, MQUEUE_STANDARD_NAME_LENGTH, NULL);
149     ASSERT_EQ(ret, strlen(msgptr));
150     ASSERT_STREQ(msgrcd, msgptr);
151 }
152 
ItIpcContainer003(void)153 void ItIpcContainer003(void)
154 {
155     auto pid = fork();
156     ASSERT_TRUE(pid != -1);
157     if (pid == 0) {
158         IpcContainerUnshare();
159         exit(0);
160     }
161     auto ret = waitpid(pid, NULL, 0);
162     ASSERT_EQ(ret, pid);
163 }
164