• 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 
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