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
31 #ifdef LOSCFG_KERNEL_CONTAINER
32 #include "los_container_pri.h"
33 #include "los_process_pri.h"
34 #include "internal.h"
35
36 STATIC Container g_rootContainer;
37 STATIC ContainerLimit g_containerLimit;
38 STATIC Atomic g_containerCount = 0xF0000000U;
39 #ifdef LOSCFG_USER_CONTAINER
40 STATIC Credentials *g_rootCredentials = NULL;
41 #endif
42
OsAllocContainerID(VOID)43 UINT32 OsAllocContainerID(VOID)
44 {
45 return LOS_AtomicIncRet(&g_containerCount);
46 }
47
OsContainerInitSystemProcess(LosProcessCB * processCB)48 VOID OsContainerInitSystemProcess(LosProcessCB *processCB)
49 {
50 processCB->container = &g_rootContainer;
51 #ifdef LOSCFG_USER_CONTAINER
52 processCB->credentials = g_rootCredentials;
53 #endif
54 LOS_AtomicInc(&processCB->container->rc);
55 #ifdef LOSCFG_PID_CONTAINER
56 (VOID)OsAllocSpecifiedVpidUnsafe(processCB->processID, processCB->container->pidContainer, processCB, NULL);
57 #endif
58 return;
59 }
60
OsGetContainerLimit(ContainerType type)61 UINT32 OsGetContainerLimit(ContainerType type)
62 {
63 switch (type) {
64 #ifdef LOSCFG_PID_CONTAINER
65 case PID_CONTAINER:
66 case PID_CHILD_CONTAINER:
67 return g_containerLimit.pidLimit;
68 #endif
69 #ifdef LOSCFG_USER_CONTAINER
70 case USER_CONTAINER:
71 return g_containerLimit.userLimit;
72 #endif
73 #ifdef LOSCFG_UTS_CONTAINER
74 case UTS_CONTAINER:
75 return g_containerLimit.utsLimit;
76 #endif
77 #ifdef LOSCFG_MNT_CONTAINER
78 case MNT_CONTAINER:
79 return g_containerLimit.mntLimit;
80 #endif
81 #ifdef LOSCFG_IPC_CONTAINER
82 case IPC_CONTAINER:
83 return g_containerLimit.ipcLimit;
84 #endif
85 #ifdef LOSCFG_TIME_CONTAINER
86 case TIME_CONTAINER:
87 case TIME_CHILD_CONTAINER:
88 return g_containerLimit.timeLimit;
89 #endif
90 #ifdef LOSCFG_NET_CONTAINER
91 case NET_CONTAINER:
92 return g_containerLimit.netLimit;
93 #endif
94 default:
95 break;
96 }
97 return OS_INVALID_VALUE;
98 }
99
OsContainerLimitCheck(ContainerType type,UINT32 * containerCount)100 UINT32 OsContainerLimitCheck(ContainerType type, UINT32 *containerCount)
101 {
102 UINT32 intSave;
103 SCHEDULER_LOCK(intSave);
104 if ((*containerCount) >= OsGetContainerLimit(type)) {
105 SCHEDULER_UNLOCK(intSave);
106 return EINVAL;
107 }
108 SCHEDULER_UNLOCK(intSave);
109 return LOS_OK;
110 }
111
OsSetContainerLimit(ContainerType type,UINT32 value)112 UINT32 OsSetContainerLimit(ContainerType type, UINT32 value)
113 {
114 UINT32 intSave;
115
116 if (value > LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT) {
117 return EINVAL;
118 }
119
120 SCHEDULER_LOCK(intSave);
121 switch (type) {
122 #ifdef LOSCFG_PID_CONTAINER
123 case PID_CONTAINER:
124 case PID_CHILD_CONTAINER:
125 g_containerLimit.pidLimit = value;
126 break;
127 #endif
128 #ifdef LOSCFG_USER_CONTAINER
129 case USER_CONTAINER:
130 g_containerLimit.userLimit = value;
131 break;
132 #endif
133 #ifdef LOSCFG_UTS_CONTAINER
134 case UTS_CONTAINER:
135 g_containerLimit.utsLimit = value;
136 break;
137 #endif
138 #ifdef LOSCFG_MNT_CONTAINER
139 case MNT_CONTAINER:
140 g_containerLimit.mntLimit = value;
141 break;
142 #endif
143 #ifdef LOSCFG_IPC_CONTAINER
144 case IPC_CONTAINER:
145 g_containerLimit.ipcLimit = value;
146 break;
147 #endif
148 #ifdef LOSCFG_TIME_CONTAINER
149 case TIME_CONTAINER:
150 case TIME_CHILD_CONTAINER:
151 g_containerLimit.timeLimit = value;
152 break;
153 #endif
154 #ifdef LOSCFG_NET_CONTAINER
155 case NET_CONTAINER:
156 g_containerLimit.netLimit = value;
157 break;
158 #endif
159 default:
160 SCHEDULER_UNLOCK(intSave);
161 return EINVAL;
162 }
163 SCHEDULER_UNLOCK(intSave);
164 return LOS_OK;
165 }
166
OsGetContainerCount(ContainerType type)167 UINT32 OsGetContainerCount(ContainerType type)
168 {
169 switch (type) {
170 #ifdef LOSCFG_PID_CONTAINER
171 case PID_CONTAINER:
172 case PID_CHILD_CONTAINER:
173 return OsGetPidContainerCount();
174 #endif
175 #ifdef LOSCFG_USER_CONTAINER
176 case USER_CONTAINER:
177 return OsGetUserContainerCount();
178 #endif
179 #ifdef LOSCFG_UTS_CONTAINER
180 case UTS_CONTAINER:
181 return OsGetUtsContainerCount();
182 #endif
183 #ifdef LOSCFG_MNT_CONTAINER
184 case MNT_CONTAINER:
185 return OsGetMntContainerCount();
186 #endif
187 #ifdef LOSCFG_IPC_CONTAINER
188 case IPC_CONTAINER:
189 return OsGetIpcContainerCount();
190 #endif
191 #ifdef LOSCFG_TIME_CONTAINER
192 case TIME_CONTAINER:
193 case TIME_CHILD_CONTAINER:
194 return OsGetTimeContainerCount();
195 #endif
196 #ifdef LOSCFG_NET_CONTAINER
197 case NET_CONTAINER:
198 return OsGetNetContainerCount();
199 #endif
200 default:
201 break;
202 }
203 return OS_INVALID_VALUE;
204 }
205
OsInitRootContainer(VOID)206 VOID OsInitRootContainer(VOID)
207 {
208 #ifdef LOSCFG_USER_CONTAINER
209 g_containerLimit.userLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT;
210 OsInitRootUserCredentials(&g_rootCredentials);
211 #endif
212 #ifdef LOSCFG_PID_CONTAINER
213 g_containerLimit.pidLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT;
214 (VOID)OsInitRootPidContainer(&g_rootContainer.pidContainer);
215 g_rootContainer.pidForChildContainer = g_rootContainer.pidContainer;
216 #endif
217 #ifdef LOSCFG_UTS_CONTAINER
218 g_containerLimit.utsLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT;
219 (VOID)OsInitRootUtsContainer(&g_rootContainer.utsContainer);
220 #endif
221 #ifdef LOSCFG_MNT_CONTAINER
222 g_containerLimit.mntLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT;
223 (VOID)OsInitRootMntContainer(&g_rootContainer.mntContainer);
224 #endif
225 #ifdef LOSCFG_IPC_CONTAINER
226 g_containerLimit.ipcLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT;
227 (VOID)OsInitRootIpcContainer(&g_rootContainer.ipcContainer);
228 #endif
229 #ifdef LOSCFG_TIME_CONTAINER
230 g_containerLimit.timeLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT;
231 (VOID)OsInitRootTimeContainer(&g_rootContainer.timeContainer);
232 g_rootContainer.timeForChildContainer = g_rootContainer.timeContainer;
233 #endif
234 #ifdef LOSCFG_NET_CONTAINER
235 g_containerLimit.netLimit = LOSCFG_KERNEL_CONTAINER_DEFAULT_LIMIT;
236 (VOID)OsInitRootNetContainer(&g_rootContainer.netContainer);
237 #endif
238 return;
239 }
240
CreateContainer(VOID)241 STATIC INLINE Container *CreateContainer(VOID)
242 {
243 Container *container = (Container *)LOS_MemAlloc(m_aucSysMem1, sizeof(Container));
244 if (container == NULL) {
245 return NULL;
246 }
247
248 (VOID)memset_s(container, sizeof(Container), 0, sizeof(Container));
249
250 LOS_AtomicInc(&container->rc);
251 return container;
252 }
253
CopyContainers(UINTPTR flags,LosProcessCB * child,LosProcessCB * parent,UINT32 * processID)254 STATIC UINT32 CopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID)
255 {
256 UINT32 ret = LOS_OK;
257 /* Pid container initialization must precede other container initialization. */
258 #ifdef LOSCFG_PID_CONTAINER
259 ret = OsCopyPidContainer(flags, child, parent, processID);
260 if (ret != LOS_OK) {
261 return ret;
262 }
263 #endif
264 #ifdef LOSCFG_USER_CONTAINER
265 ret = OsCopyCredentials(flags, child, parent);
266 if (ret != LOS_OK) {
267 return ret;
268 }
269 #endif
270 #ifdef LOSCFG_UTS_CONTAINER
271 ret = OsCopyUtsContainer(flags, child, parent);
272 if (ret != LOS_OK) {
273 return ret;
274 }
275 #endif
276 #ifdef LOSCFG_MNT_CONTAINER
277 ret = OsCopyMntContainer(flags, child, parent);
278 if (ret != LOS_OK) {
279 return ret;
280 }
281 #endif
282 #ifdef LOSCFG_IPC_CONTAINER
283 ret = OsCopyIpcContainer(flags, child, parent);
284 if (ret != LOS_OK) {
285 return ret;
286 }
287 #endif
288 #ifdef LOSCFG_TIME_CONTAINER
289 ret = OsCopyTimeContainer(flags, child, parent);
290 if (ret != LOS_OK) {
291 return ret;
292 }
293 #endif
294 #ifdef LOSCFG_NET_CONTAINER
295 ret = OsCopyNetContainer(flags, child, parent);
296 if (ret != LOS_OK) {
297 return ret;
298 }
299 #endif
300 return ret;
301 }
302
GetContainerFlagsMask(VOID)303 STATIC INLINE UINT32 GetContainerFlagsMask(VOID)
304 {
305 UINT32 mask = 0;
306 #ifdef LOSCFG_PID_CONTAINER
307 mask |= CLONE_NEWPID;
308 #endif
309 #ifdef LOSCFG_MNT_CONTAINER
310 mask |= CLONE_NEWNS;
311 #endif
312 #ifdef LOSCFG_IPC_CONTAINER
313 mask |= CLONE_NEWIPC;
314 #endif
315 #ifdef LOSCFG_USER_CONTAINER
316 mask |= CLONE_NEWUSER;
317 #endif
318 #ifdef LOSCFG_TIME_CONTAINER
319 mask |= CLONE_NEWTIME;
320 #endif
321 #ifdef LOSCFG_NET_CONTAINER
322 mask |= CLONE_NEWNET;
323 #endif
324 #ifdef LOSCFG_UTS_CONTAINER
325 mask |= CLONE_NEWUTS;
326 #endif
327 return mask;
328 }
329
330 /*
331 * called from clone. This now handles copy for Container and all
332 * namespaces therein.
333 */
OsCopyContainers(UINTPTR flags,LosProcessCB * child,LosProcessCB * parent,UINT32 * processID)334 UINT32 OsCopyContainers(UINTPTR flags, LosProcessCB *child, LosProcessCB *parent, UINT32 *processID)
335 {
336 UINT32 intSave;
337
338 #ifdef LOSCFG_TIME_CONTAINER
339 flags &= ~CLONE_NEWTIME;
340 #endif
341
342 if (!(flags & GetContainerFlagsMask())) {
343 #ifdef LOSCFG_PID_CONTAINER
344 if (parent->container->pidContainer != parent->container->pidForChildContainer) {
345 goto CREATE_CONTAINER;
346 }
347 #endif
348 #ifdef LOSCFG_TIME_CONTAINER
349 if (parent->container->timeContainer != parent->container->timeForChildContainer) {
350 goto CREATE_CONTAINER;
351 }
352 #endif
353 SCHEDULER_LOCK(intSave);
354 child->container = parent->container;
355 LOS_AtomicInc(&child->container->rc);
356 SCHEDULER_UNLOCK(intSave);
357 goto COPY_CONTAINERS;
358 }
359
360 #if defined(LOSCFG_PID_CONTAINER) || defined(LOSCFG_TIME_CONTAINER)
361 CREATE_CONTAINER:
362 #endif
363 child->container = CreateContainer();
364 if (child->container == NULL) {
365 return ENOMEM;
366 }
367
368 COPY_CONTAINERS:
369 return CopyContainers(flags, child, parent, processID);
370 }
371
OsContainerFree(LosProcessCB * processCB)372 VOID OsContainerFree(LosProcessCB *processCB)
373 {
374 LOS_AtomicDec(&processCB->container->rc);
375 if (LOS_AtomicRead(&processCB->container->rc) == 0) {
376 (VOID)LOS_MemFree(m_aucSysMem1, processCB->container);
377 processCB->container = NULL;
378 }
379 }
380
OsOsContainersDestroyEarly(LosProcessCB * processCB)381 VOID OsOsContainersDestroyEarly(LosProcessCB *processCB)
382 {
383 /* All processes in the container must be destroyed before the container is destroyed. */
384 #ifdef LOSCFG_PID_CONTAINER
385 if (processCB->processID == OS_USER_ROOT_PROCESS_ID) {
386 OsPidContainerDestroyAllProcess(processCB);
387 }
388 #endif
389
390 #ifdef LOSCFG_MNT_CONTAINER
391 OsMntContainerDestroy(processCB->container);
392 #endif
393 }
394
OsContainersDestroy(LosProcessCB * processCB)395 VOID OsContainersDestroy(LosProcessCB *processCB)
396 {
397 #ifdef LOSCFG_USER_CONTAINER
398 OsUserContainerDestroy(processCB);
399 #endif
400
401 #ifdef LOSCFG_UTS_CONTAINER
402 OsUtsContainerDestroy(processCB->container);
403 #endif
404
405 #ifdef LOSCFG_IPC_CONTAINER
406 OsIpcContainerDestroy(processCB->container);
407 #endif
408
409 #ifdef LOSCFG_TIME_CONTAINER
410 OsTimeContainerDestroy(processCB->container);
411 #endif
412
413 #ifdef LOSCFG_NET_CONTAINER
414 OsNetContainerDestroy(processCB->container);
415 #endif
416
417 #ifndef LOSCFG_PID_CONTAINER
418 UINT32 intSave;
419 SCHEDULER_LOCK(intSave);
420 OsContainerFree(processCB);
421 SCHEDULER_UNLOCK(intSave);
422 #endif
423 }
424
DeInitContainers(UINT32 flags,Container * container,LosProcessCB * processCB)425 STATIC VOID DeInitContainers(UINT32 flags, Container *container, LosProcessCB *processCB)
426 {
427 UINT32 intSave;
428 if (container == NULL) {
429 return;
430 }
431
432 #ifdef LOSCFG_PID_CONTAINER
433 SCHEDULER_LOCK(intSave);
434 if ((flags & CLONE_NEWPID) != 0) {
435 OsPidContainerDestroy(container, processCB);
436 } else {
437 OsPidContainerDestroy(container, NULL);
438 }
439 SCHEDULER_UNLOCK(intSave);
440 #endif
441
442 #ifdef LOSCFG_UTS_CONTAINER
443 OsUtsContainerDestroy(container);
444 #endif
445 #ifdef LOSCFG_MNT_CONTAINER
446 OsMntContainerDestroy(container);
447 #endif
448 #ifdef LOSCFG_IPC_CONTAINER
449 OsIpcContainerDestroy(container);
450 #endif
451
452 #ifdef LOSCFG_TIME_CONTAINER
453 OsTimeContainerDestroy(container);
454 #endif
455
456 #ifdef LOSCFG_NET_CONTAINER
457 OsNetContainerDestroy(container);
458 #endif
459
460 SCHEDULER_LOCK(intSave);
461 LOS_AtomicDec(&container->rc);
462 if (LOS_AtomicRead(&container->rc) == 0) {
463 (VOID)LOS_MemFree(m_aucSysMem1, container);
464 }
465 SCHEDULER_UNLOCK(intSave);
466 }
467
OsGetContainerID(LosProcessCB * processCB,ContainerType type)468 UINT32 OsGetContainerID(LosProcessCB *processCB, ContainerType type)
469 {
470 Container *container = processCB->container;
471 if (container == NULL) {
472 return OS_INVALID_VALUE;
473 }
474
475 switch (type) {
476 #ifdef LOSCFG_PID_CONTAINER
477 case PID_CONTAINER:
478 return OsGetPidContainerID(container->pidContainer);
479 case PID_CHILD_CONTAINER:
480 return OsGetPidContainerID(container->pidForChildContainer);
481 #endif
482 #ifdef LOSCFG_USER_CONTAINER
483 case USER_CONTAINER:
484 return OsGetUserContainerID(processCB->credentials);
485 #endif
486 #ifdef LOSCFG_UTS_CONTAINER
487 case UTS_CONTAINER:
488 return OsGetUtsContainerID(container->utsContainer);
489 #endif
490 #ifdef LOSCFG_MNT_CONTAINER
491 case MNT_CONTAINER:
492 return OsGetMntContainerID(container->mntContainer);
493 #endif
494 #ifdef LOSCFG_IPC_CONTAINER
495 case IPC_CONTAINER:
496 return OsGetIpcContainerID(container->ipcContainer);
497 #endif
498 #ifdef LOSCFG_TIME_CONTAINER
499 case TIME_CONTAINER:
500 return OsGetTimeContainerID(container->timeContainer);
501 case TIME_CHILD_CONTAINER:
502 return OsGetTimeContainerID(container->timeForChildContainer);
503 #endif
504 #ifdef LOSCFG_NET_CONTAINER
505 case NET_CONTAINER:
506 return OsGetNetContainerID(container->netContainer);
507 #endif
508 default:
509 break;
510 }
511 return OS_INVALID_VALUE;
512 }
513
UnshareCreateNewContainers(UINT32 flags,LosProcessCB * curr,Container * newContainer)514 STATIC UINT32 UnshareCreateNewContainers(UINT32 flags, LosProcessCB *curr, Container *newContainer)
515 {
516 UINT32 ret = LOS_OK;
517 #ifdef LOSCFG_PID_CONTAINER
518 ret = OsUnsharePidContainer(flags, curr, newContainer);
519 if (ret != LOS_OK) {
520 return ret;
521 }
522 #endif
523 #ifdef LOSCFG_UTS_CONTAINER
524 ret = OsUnshareUtsContainer(flags, curr, newContainer);
525 if (ret != LOS_OK) {
526 return ret;
527 }
528 #endif
529 #ifdef LOSCFG_MNT_CONTAINER
530 ret = OsUnshareMntContainer(flags, curr, newContainer);
531 if (ret != LOS_OK) {
532 return ret;
533 }
534 #endif
535 #ifdef LOSCFG_IPC_CONTAINER
536 ret = OsUnshareIpcContainer(flags, curr, newContainer);
537 if (ret != LOS_OK) {
538 return ret;
539 }
540 #endif
541 #ifdef LOSCFG_TIME_CONTAINER
542 ret = OsUnshareTimeContainer(flags, curr, newContainer);
543 if (ret != LOS_OK) {
544 return ret;
545 }
546 #endif
547 #ifdef LOSCFG_NET_CONTAINER
548 ret = OsUnshareNetContainer(flags, curr, newContainer);
549 if (ret != LOS_OK) {
550 return ret;
551 }
552 #endif
553 return ret;
554 }
555
OsUnshare(UINT32 flags)556 INT32 OsUnshare(UINT32 flags)
557 {
558 UINT32 ret;
559 UINT32 intSave;
560 LosProcessCB *curr = OsCurrProcessGet();
561 Container *oldContainer = curr->container;
562 UINT32 unshareFlags = GetContainerFlagsMask();
563 if (!(flags & unshareFlags) || ((flags & (~unshareFlags)) != 0)) {
564 return -EINVAL;
565 }
566
567 #ifdef LOSCFG_USER_CONTAINER
568 ret = OsUnshareUserCredentials(flags, curr);
569 if (ret != LOS_OK) {
570 return ret;
571 }
572 if (flags == CLONE_NEWUSER) {
573 return LOS_OK;
574 }
575 #endif
576
577 Container *newContainer = CreateContainer();
578 if (newContainer == NULL) {
579 return -ENOMEM;
580 }
581
582 ret = UnshareCreateNewContainers(flags, curr, newContainer);
583 if (ret != LOS_OK) {
584 goto EXIT;
585 }
586
587 SCHEDULER_LOCK(intSave);
588 oldContainer = curr->container;
589 curr->container = newContainer;
590 SCHEDULER_UNLOCK(intSave);
591
592 DeInitContainers(flags, oldContainer, NULL);
593 return LOS_OK;
594
595 EXIT:
596 DeInitContainers(flags, newContainer, NULL);
597 return -ret;
598 }
599
SetNsGetFlagByContainerType(UINT32 containerType)600 STATIC UINT32 SetNsGetFlagByContainerType(UINT32 containerType)
601 {
602 if (containerType >= (UINT32)CONTAINER_MAX) {
603 return 0;
604 }
605 ContainerType type = (ContainerType)containerType;
606 switch (type) {
607 case PID_CONTAINER:
608 case PID_CHILD_CONTAINER:
609 return CLONE_NEWPID;
610 case USER_CONTAINER:
611 return CLONE_NEWUSER;
612 case UTS_CONTAINER:
613 return CLONE_NEWUTS;
614 case MNT_CONTAINER:
615 return CLONE_NEWNS;
616 case IPC_CONTAINER:
617 return CLONE_NEWIPC;
618 case TIME_CONTAINER:
619 case TIME_CHILD_CONTAINER:
620 return CLONE_NEWTIME;
621 case NET_CONTAINER:
622 return CLONE_NEWNET;
623 default:
624 break;
625 }
626 return 0;
627 }
628
SetNsCreateNewContainers(UINT32 flags,Container * newContainer,Container * container)629 STATIC UINT32 SetNsCreateNewContainers(UINT32 flags, Container *newContainer, Container *container)
630 {
631 UINT32 ret = LOS_OK;
632 #ifdef LOSCFG_PID_CONTAINER
633 ret = OsSetNsPidContainer(flags, container, newContainer);
634 if (ret != LOS_OK) {
635 return ret;
636 }
637 #endif
638 #ifdef LOSCFG_UTS_CONTAINER
639 ret = OsSetNsUtsContainer(flags, container, newContainer);
640 if (ret != LOS_OK) {
641 return ret;
642 }
643 #endif
644 #ifdef LOSCFG_MNT_CONTAINER
645 ret = OsSetNsMntContainer(flags, container, newContainer);
646 if (ret != LOS_OK) {
647 return ret;
648 }
649 #endif
650 #ifdef LOSCFG_IPC_CONTAINER
651 ret = OsSetNsIpcContainer(flags, container, newContainer);
652 if (ret != LOS_OK) {
653 return ret;
654 }
655 #endif
656 #ifdef LOSCFG_TIME_CONTAINER
657 ret = OsSetNsTimeContainer(flags, container, newContainer);
658 if (ret != LOS_OK) {
659 return ret;
660 }
661 #endif
662 #ifdef LOSCFG_NET_CONTAINER
663 ret = OsSetNsNetContainer(flags, container, newContainer);
664 if (ret != LOS_OK) {
665 return ret;
666 }
667 #endif
668 return LOS_OK;
669 }
670
SetNsParamCheck(INT32 fd,INT32 type,UINT32 * flag,LosProcessCB ** target)671 STATIC UINT32 SetNsParamCheck(INT32 fd, INT32 type, UINT32 *flag, LosProcessCB **target)
672 {
673 UINT32 typeMask = GetContainerFlagsMask();
674 *flag = (UINT32)(type & typeMask);
675 UINT32 containerType = 0;
676
677 if (((type & (~typeMask)) != 0)) {
678 return EINVAL;
679 }
680
681 LosProcessCB *processCB = (LosProcessCB *)ProcfsContainerGet(fd, &containerType);
682 if (processCB == NULL) {
683 return EBADF;
684 }
685
686 if (*flag == 0) {
687 *flag = SetNsGetFlagByContainerType(containerType);
688 }
689
690 if ((*flag == 0) || (*flag != SetNsGetFlagByContainerType(containerType))) {
691 return EINVAL;
692 }
693
694 if (processCB == OsCurrProcessGet()) {
695 return EINVAL;
696 }
697 *target = processCB;
698 return LOS_OK;
699 }
700
OsSetNs(INT32 fd,INT32 type)701 INT32 OsSetNs(INT32 fd, INT32 type)
702 {
703 UINT32 intSave, ret;
704 UINT32 flag = 0;
705 LosProcessCB *curr = OsCurrProcessGet();
706 LosProcessCB *processCB = NULL;
707
708 ret = SetNsParamCheck(fd, type, &flag, &processCB);
709 if (ret != LOS_OK) {
710 return -ret;
711 }
712
713 #ifdef LOSCFG_USER_CONTAINER
714 if (flag == CLONE_NEWUSER) {
715 SCHEDULER_LOCK(intSave);
716 if ((processCB->credentials == NULL) || (processCB->credentials->userContainer == NULL)) {
717 SCHEDULER_UNLOCK(intSave);
718 return -EBADF;
719 }
720 UserContainer *userContainer = processCB->credentials->userContainer;
721 ret = OsSetNsUserContainer(userContainer, curr);
722 SCHEDULER_UNLOCK(intSave);
723 return ret;
724 }
725 #endif
726
727 Container *newContainer = CreateContainer();
728 if (newContainer == NULL) {
729 return -ENOMEM;
730 }
731
732 SCHEDULER_LOCK(intSave);
733 Container *targetContainer = processCB->container;
734 if (targetContainer == NULL) {
735 SCHEDULER_UNLOCK(intSave);
736 return -EBADF;
737 }
738
739 ret = SetNsCreateNewContainers(flag, newContainer, targetContainer);
740 if (ret != LOS_OK) {
741 SCHEDULER_UNLOCK(intSave);
742 goto EXIT;
743 }
744
745 Container *oldContainer = curr->container;
746 curr->container = newContainer;
747 SCHEDULER_UNLOCK(intSave);
748 DeInitContainers(flag, oldContainer, NULL);
749 return LOS_OK;
750
751 EXIT:
752 DeInitContainers(flag, newContainer, curr);
753 return ret;
754 }
755 #endif
756