• 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 "It_container_test.h"
31 using namespace std;
32 
33 static const char testBuf[] = "test shm";
34 static const char *containerType = "ipc";
35 struct shared_use_st {
36     char test[SHM_TEST_DATA_SIZE];
37 };
38 
childFunc1(void * arg)39 static int childFunc1(void *arg)
40 {
41     struct shared_use_st *shared = NULL;
42     int ret;
43     (void)arg;
44     const int sleep_num = 3; /* 3: delay */
45 
46     int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT);
47     if (shmid == -1) {
48         return EXIT_CODE_ERRNO_1;
49     }
50 
51     void *shm = shmat(shmid, 0, 0);
52     if (shm == reinterpret_cast<void *>(-1)) {
53         shmctl(shmid, IPC_RMID, 0);
54         return EXIT_CODE_ERRNO_2;
55     }
56     shared = (struct shared_use_st *)shm;
57     sleep(sleep_num);
58     ret = strncmp(shared->test, testBuf, strlen(testBuf));
59     if (ret != 0) {
60         shmdt(shm);
61         shmctl(shmid, IPC_RMID, 0);
62         return EXIT_CODE_ERRNO_3;
63     }
64 
65     ret = shmdt(shm);
66     if (ret ==  -1) {
67         shmctl(shmid, IPC_RMID, 0);
68         return EXIT_CODE_ERRNO_4;
69     }
70     return 0;
71 }
72 
childFunc(void * arg)73 static int childFunc(void *arg)
74 {
75     struct shared_use_st *shared = NULL;
76     int ret;
77     (void)arg;
78     int status;
79     int exitCode;
80     const int sleep_num = 1;
81     auto linkBuffer = ReadlinkContainer(getpid(), containerType);
82     char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK,
83                                -1, 0);
84     if (stack == nullptr) {
85         return EXIT_CODE_ERRNO_17;
86     }
87     char *stackTop = stack + STACK_SIZE;
88 
89     auto pid = clone(childFunc1, stackTop, CLONE_NEWIPC | SIGCHLD, &arg);
90     if (pid == -1) {
91         return EXIT_CODE_ERRNO_6;
92     }
93 
94     std::string filePath = GenContainerLinkPath(pid, containerType);
95     int fd = open(filePath.c_str(), O_RDONLY);
96     if (fd == -1) {
97         return EXIT_CODE_ERRNO_7;
98     }
99     sleep(sleep_num);
100     ret = setns(fd, CLONE_NEWIPC);
101     if (ret == -1) {
102         close(fd);
103         return EXIT_CODE_ERRNO_8;
104     }
105     close(fd);
106     auto linkBuffer1 = ReadlinkContainer(getpid(), containerType);
107     auto linkBuffer2 = ReadlinkContainer(pid, containerType);
108     ret = linkBuffer.compare(linkBuffer1);
109     if (ret == 0) {
110         return EXIT_CODE_ERRNO_9;
111     }
112     ret = linkBuffer1.compare(linkBuffer2);
113     if (ret != 0) {
114         return EXIT_CODE_ERRNO_10;
115     }
116 
117     int shmid = shmget((key_t)SHM_TEST_KEY1, sizeof(struct shared_use_st), SHM_TEST_OPEN_PERM | IPC_CREAT);
118     if (shmid == -1) {
119         return EXIT_CODE_ERRNO_11;
120     }
121 
122     void *shm = shmat(shmid, 0, 0);
123     if (shm == reinterpret_cast<void *>(-1)) {
124         shmctl(shmid, IPC_RMID, 0);
125         return EXIT_CODE_ERRNO_12;
126     }
127 
128     shared = (struct shared_use_st *)shm;
129 
130     ret = memcpy_s(shared->test, sizeof(struct shared_use_st), testBuf, sizeof(testBuf));
131     if (ret != 0) {
132         shmctl(shmid, IPC_RMID, 0);
133         return EXIT_CODE_ERRNO_13;
134     }
135 
136     ret = waitpid(pid, &status, 0);
137     if (ret != pid) {
138         shmdt(shm);
139         shmctl(shmid, IPC_RMID, 0);
140         return EXIT_CODE_ERRNO_14;
141     }
142 
143     exitCode = WEXITSTATUS(status);
144     if (exitCode != 0) {
145         shmdt(shm);
146         shmctl(shmid, IPC_RMID, 0);
147         return EXIT_CODE_ERRNO_15;
148     }
149 
150     ret = shmdt(shm);
151     if (ret == -1) {
152         shmctl(shmid, IPC_RMID, 0);
153         return EXIT_CODE_ERRNO_16;
154     }
155 
156     ret = shmctl(shmid, IPC_RMID, 0);
157     if (ret == -1) {
158         return EXIT_CODE_ERRNO_255;
159     }
160     return 0;
161 }
162 
ItIpcContainer006(void)163 void ItIpcContainer006(void)
164 {
165     int ret;
166     int status;
167     char *stack = (char *)mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK,
168                                -1, 0);
169     ASSERT_NE(stack, nullptr);
170     char *stackTop = stack + STACK_SIZE;
171 
172     int arg = CHILD_FUNC_ARG;
173     auto pid = clone(childFunc, stackTop, CLONE_NEWIPC | SIGCHLD, &arg);
174     ASSERT_NE(pid, -1);
175 
176     ret = waitpid(pid, &status, 0);
177     ASSERT_EQ(ret, pid);
178 
179     ret = WIFEXITED(status);
180     ASSERT_NE(ret, 0);
181 
182     int exitCode = WEXITSTATUS(status);
183     ASSERT_EQ(exitCode, 0);
184 }
185