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 "sandbox_adapter.h"
17 #include "init_utils.h"
18 
19 #ifdef WITH_SELINUX
20 #include "hap_restorecon.h"
21 #endif
22 
MakeAtomicServiceDir(const SandboxContext *context, const char *path)23 void MakeAtomicServiceDir(const SandboxContext *context, const char *path)
24 {
25     APPSPAWN_CHECK_ONLY_EXPER(context != NULL && path != NULL, return);
26     if (access(path, F_OK) == 0) {
27         APPSPAWN_LOGV("path %{public}s already exist, no need to recreate", path);
28         return;
29     }
30     int ret = mkdir(path, S_IRWXU);
31     APPSPAWN_CHECK(ret == 0, return, "mkdir %{public}s failed, errno %{public}d", path, errno);
32 
33     if (strstr(path, "/database") != NULL) {
34         ret = chmod(path, S_IRWXU | S_IRWXG | S_ISGID);
35     } else if (strstr(path, "/log") != NULL) {
36         ret = chmod(path, S_IRWXU | S_IRWXG);
37     }
38     APPSPAWN_CHECK(ret == 0, return, "chmod %{public}s failed, errno %{public}d", path, errno);
39 
40 #ifdef WITH_SELINUX
41     AppSpawnMsgDomainInfo *msgDomainInfo = (AppSpawnMsgDomainInfo *)GetSpawningMsgInfo(context, TLV_DOMAIN_INFO);
42     APPSPAWN_CHECK(msgDomainInfo != NULL, return, "No domain info for %{public}s", context->bundleName);
43     HapContext hapContext;
44     HapFileInfo hapFileInfo;
45     hapFileInfo.pathNameOrig.push_back(path);
46     hapFileInfo.apl = msgDomainInfo->apl;
47     hapFileInfo.packageName = context->bundleName;
48     hapFileInfo.hapFlags = msgDomainInfo->hapFlags;
49     if (CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_DEBUGGABLE)) {
50         hapFileInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE;
51     }
52     if ((strstr(path, "/base") != NULL) || (strstr(path, "/database") != NULL)) {
53         ret = hapContext.HapFileRestorecon(hapFileInfo);
54         APPSPAWN_CHECK(ret == 0, return, "set dir %{public}s selinuxLabel failed, apl %{public}s, ret %{public}d",
55             path, hapFileInfo.apl.c_str(), ret);
56     }
57 #endif
58     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetSpawningMsgInfo(context, TLV_DAC_INFO);
59     APPSPAWN_CHECK(dacInfo != NULL, return, "No dac info for %{public}s", context->bundleName);
60     if (strstr(path, "/base") != NULL) {
61         ret = chown(path, dacInfo->uid, dacInfo->gid);
62     } else if (strstr(path, "/database") != NULL) {
63         ret = chown(path, dacInfo->uid, DecodeGid("ddms"));
64     } else if (strstr(path, "/log") != NULL) {
65         ret = chown(path, dacInfo->uid, DecodeGid("log"));
66     }
67     APPSPAWN_CHECK(ret == 0, return, "chown %{public}s failed, errno %{public}d", path, errno);
68 }
69