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 #include <errno.h>
32 #include "los_credentials_pri.h"
33 #include "los_user_container_pri.h"
34 #include "los_config.h"
35 #include "los_memory.h"
36 #include "los_process_pri.h"
37
38 #ifdef LOSCFG_USER_CONTAINER
CreateNewCredential(LosProcessCB * parent)39 STATIC Credentials *CreateNewCredential(LosProcessCB *parent)
40 {
41 UINT32 size = sizeof(Credentials);
42 Credentials *newCredentials = LOS_MemAlloc(m_aucSysMem1, size);
43 if (newCredentials == NULL) {
44 return NULL;
45 }
46
47 if (parent != NULL) {
48 const Credentials *oldCredentials = parent->credentials;
49 (VOID)memcpy_s(newCredentials, sizeof(Credentials), oldCredentials, sizeof(Credentials));
50 LOS_AtomicSet(&newCredentials->rc, 1);
51 } else {
52 (VOID)memset_s(newCredentials, sizeof(Credentials), 0, sizeof(Credentials));
53 LOS_AtomicSet(&newCredentials->rc, 3); /* 3: Three system processes */
54 }
55 newCredentials->userContainer = NULL;
56 return newCredentials;
57 }
58
PrepareCredential(LosProcessCB * runProcessCB)59 Credentials *PrepareCredential(LosProcessCB *runProcessCB)
60 {
61 Credentials *newCredentials = CreateNewCredential(runProcessCB);
62 if (newCredentials == NULL) {
63 return NULL;
64 }
65
66 newCredentials->userContainer = runProcessCB->credentials->userContainer;
67 LOS_AtomicInc(&newCredentials->userContainer->rc);
68 return newCredentials;
69 }
70
FreeCredential(Credentials * credentials)71 VOID FreeCredential(Credentials *credentials)
72 {
73 if (credentials == NULL) {
74 return;
75 }
76
77 if (credentials->userContainer != NULL) {
78 LOS_AtomicDec(&credentials->userContainer->rc);
79 if (LOS_AtomicRead(&credentials->userContainer->rc) <= 0) {
80 FreeUserContainer(credentials->userContainer);
81 credentials->userContainer = NULL;
82 }
83 }
84
85 LOS_AtomicDec(&credentials->rc);
86 if (LOS_AtomicRead(&credentials->rc) <= 0) {
87 (VOID)LOS_MemFree(m_aucSysMem1, credentials);
88 }
89 }
90
OsUserContainerDestroy(LosProcessCB * curr)91 VOID OsUserContainerDestroy(LosProcessCB *curr)
92 {
93 UINT32 intSave;
94 SCHEDULER_LOCK(intSave);
95 FreeCredential(curr->credentials);
96 curr->credentials = NULL;
97 SCHEDULER_UNLOCK(intSave);
98 return;
99 }
100
CreateCredentials(unsigned long flags,LosProcessCB * parent)101 STATIC Credentials *CreateCredentials(unsigned long flags, LosProcessCB *parent)
102 {
103 UINT32 ret;
104 Credentials *newCredentials = CreateNewCredential(parent);
105 if (newCredentials == NULL) {
106 return NULL;
107 }
108
109 if (!(flags & CLONE_NEWUSER)) {
110 newCredentials->userContainer = parent->credentials->userContainer;
111 LOS_AtomicInc(&newCredentials->userContainer->rc);
112 return newCredentials;
113 }
114
115 if (parent != NULL) {
116 ret = OsCreateUserContainer(newCredentials, parent->credentials->userContainer);
117 } else {
118 ret = OsCreateUserContainer(newCredentials, NULL);
119 }
120 if (ret != LOS_OK) {
121 FreeCredential(newCredentials);
122 return NULL;
123 }
124 return newCredentials;
125 }
126
OsCopyCredentials(unsigned long flags,LosProcessCB * child,LosProcessCB * parent)127 UINT32 OsCopyCredentials(unsigned long flags, LosProcessCB *child, LosProcessCB *parent)
128 {
129 UINT32 intSave;
130
131 SCHEDULER_LOCK(intSave);
132 child->credentials = CreateCredentials(flags, parent);
133 SCHEDULER_UNLOCK(intSave);
134 if (child->credentials == NULL) {
135 return ENOMEM;
136 }
137 return LOS_OK;
138 }
139
OsInitRootUserCredentials(Credentials ** credentials)140 UINT32 OsInitRootUserCredentials(Credentials **credentials)
141 {
142 *credentials = CreateCredentials(CLONE_NEWUSER, NULL);
143 if (*credentials == NULL) {
144 return ENOMEM;
145 }
146 return LOS_OK;
147 }
148
OsUnshareUserCredentials(UINTPTR flags,LosProcessCB * curr)149 UINT32 OsUnshareUserCredentials(UINTPTR flags, LosProcessCB *curr)
150 {
151 UINT32 intSave;
152 if (!(flags & CLONE_NEWUSER)) {
153 return LOS_OK;
154 }
155
156 SCHEDULER_LOCK(intSave);
157 UINT32 ret = OsCreateUserContainer(curr->credentials, curr->credentials->userContainer);
158 SCHEDULER_UNLOCK(intSave);
159 return ret;
160 }
161
OsSetNsUserContainer(struct UserContainer * targetContainer,LosProcessCB * runProcess)162 UINT32 OsSetNsUserContainer(struct UserContainer *targetContainer, LosProcessCB *runProcess)
163 {
164 Credentials *oldCredentials = runProcess->credentials;
165 Credentials *newCredentials = CreateNewCredential(runProcess);
166 if (newCredentials == NULL) {
167 return ENOMEM;
168 }
169
170 runProcess->credentials = newCredentials;
171 newCredentials->userContainer = targetContainer;
172 LOS_AtomicInc(&targetContainer->rc);
173 FreeCredential(oldCredentials);
174 return LOS_OK;
175 }
176
OsGetUserContainerID(Credentials * credentials)177 UINT32 OsGetUserContainerID(Credentials *credentials)
178 {
179 if ((credentials == NULL) || (credentials->userContainer == NULL)) {
180 return OS_INVALID_VALUE;
181 }
182
183 return credentials->userContainer->containerID;
184 }
185
CommitCredentials(Credentials * newCredentials)186 INT32 CommitCredentials(Credentials *newCredentials)
187 {
188 Credentials *oldCredentials = OsCurrProcessGet()->credentials;
189
190 if (LOS_AtomicRead(&newCredentials->rc) < 1) {
191 return -EINVAL;
192 }
193
194 OsCurrProcessGet()->credentials = newCredentials;
195 FreeCredential(oldCredentials);
196 return 0;
197 }
198
CurrentCredentials(VOID)199 Credentials *CurrentCredentials(VOID)
200 {
201 return OsCurrProcessGet()->credentials;
202 }
203
OsCurrentUserContainer(VOID)204 UserContainer *OsCurrentUserContainer(VOID)
205 {
206 UserContainer *userContainer = OsCurrProcessGet()->credentials->userContainer;
207 return userContainer;
208 }
209 #endif
210