• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <string>
17 
18 #include "sandbox_adapter.h"
19 #include "init_utils.h"
20 
21 #ifdef WITH_SELINUX
22 #include "hap_restorecon.h"
23 #endif
24 
25 using namespace std;
26 
MakeAtomicServiceDir(const SandboxContext * context,const char * originPath,const char * varPackageName)27 void MakeAtomicServiceDir(const SandboxContext *context, const char *originPath, const char *varPackageName)
28 {
29     APPSPAWN_CHECK_ONLY_EXPER(context != NULL && originPath != NULL && varPackageName != NULL, return);
30     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetSandboxCtxMsgInfo(context, TLV_DAC_INFO);
31     APPSPAWN_CHECK(dacInfo != NULL, return, "No dac info for %{public}s", context->bundleName);
32     string path(originPath);
33     if (path.find("/mnt/share") != string::npos) {
34         path = "/data/service/el2/" + to_string(dacInfo->uid / UID_BASE) + "/share/" + string(varPackageName);
35     }
36     if (access(path.c_str(), F_OK) == 0) {
37         APPSPAWN_LOGV("path %{public}s already exist, no need to recreate", path.c_str());
38         return;
39     }
40     int ret = mkdir(path.c_str(), S_IRWXU);
41     APPSPAWN_CHECK(ret == 0, return, "mkdir %{public}s failed, errno %{public}d", path.c_str(), errno);
42 
43     if (path.find("/database") != string::npos || path.find("/data/service/el2") != string::npos) {
44         ret = chmod(path.c_str(), S_IRWXU | S_IRWXG | S_ISGID);
45     } else if (path.find("/log") != string::npos) {
46         ret = chmod(path.c_str(), S_IRWXU | S_IRWXG);
47     }
48     APPSPAWN_CHECK(ret == 0, return, "chmod %{public}s failed, errno %{public}d", path.c_str(), errno);
49 
50 #ifdef WITH_SELINUX
51     AppSpawnMsgDomainInfo *msgDomainInfo = (AppSpawnMsgDomainInfo *)GetSandboxCtxMsgInfo(context, TLV_DOMAIN_INFO);
52     APPSPAWN_CHECK(msgDomainInfo != NULL, return, "No domain info for %{public}s", context->bundleName);
53     HapContext hapContext;
54     HapFileInfo hapFileInfo;
55     hapFileInfo.pathNameOrig.push_back(path);
56     hapFileInfo.apl = msgDomainInfo->apl;
57     hapFileInfo.packageName = context->bundleName;
58     hapFileInfo.hapFlags = msgDomainInfo->hapFlags;
59     if (CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_DEBUGGABLE)) {
60         hapFileInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE;
61     }
62     if ((path.find("/base") != string::npos) || (path.find("/database") != string::npos)) {
63         ret = hapContext.HapFileRestorecon(hapFileInfo);
64         APPSPAWN_CHECK(ret == 0, return, "set dir %{public}s selinuxLabel failed, apl %{public}s, ret %{public}d",
65             path.c_str(), hapFileInfo.apl.c_str(), ret);
66     }
67 #endif
68     if (path.find("/base") != string::npos || path.find("/data/service/el2") != string::npos) {
69         ret = chown(path.c_str(), dacInfo->uid, dacInfo->gid);
70     } else if (path.find("/database") != string::npos) {
71         ret = chown(path.c_str(), dacInfo->uid, DecodeGid("ddms"));
72     } else if (path.find("/log") != string::npos) {
73         ret = chown(path.c_str(), dacInfo->uid, DecodeGid("log"));
74     }
75     APPSPAWN_CHECK(ret == 0, return, "chown %{public}s failed, errno %{public}d", path.c_str(), errno);
76     return;
77 }
78