1 /*
2 * Copyright (C) 2025 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_dec.h"
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include "appspawn_utils.h"
23 #include "appspawn_hook.h"
24
25 static const char *g_decConstraintDir[] = {
26 "/storage/Users",
27 "/storage/External",
28 "/storage/Share",
29 "/storage/hmdfs",
30 "/mnt/data/fuse",
31 "/mnt/debug",
32 "/storage/userExternal"
33 };
34
35 static const char *g_decForcedPrefix[] = {
36 "/storage/Users/currentUser/appdata",
37 };
38
39 static DecPolicyInfo *g_decPolicyInfos = NULL;
40
DestroyDecPolicyInfos(DecPolicyInfo * decPolicyInfos)41 void DestroyDecPolicyInfos(DecPolicyInfo *decPolicyInfos)
42 {
43 if (decPolicyInfos == NULL) {
44 return;
45 }
46 for (uint32_t i = 0; i < decPolicyInfos->pathNum; i++) {
47 if (decPolicyInfos->path[i].path) {
48 free(decPolicyInfos->path[i].path);
49 decPolicyInfos->path[i].pathLen = 0;
50 decPolicyInfos->path[i].flag = 0;
51 decPolicyInfos->path[i].mode = 0;
52 }
53 }
54 decPolicyInfos->pathNum = 0;
55 decPolicyInfos->tokenId = 0;
56 decPolicyInfos->flag = 0;
57 free(decPolicyInfos);
58 }
59
SetDecPolicyInfos(DecPolicyInfo * decPolicyInfos)60 void SetDecPolicyInfos(DecPolicyInfo *decPolicyInfos)
61 {
62 if (decPolicyInfos == NULL || decPolicyInfos->pathNum == 0) {
63 return;
64 }
65
66 if (g_decPolicyInfos == NULL) {
67 g_decPolicyInfos = (DecPolicyInfo *)calloc(1, sizeof(DecPolicyInfo));
68 if (g_decPolicyInfos == NULL) {
69 APPSPAWN_LOGE("calloc failed");
70 return;
71 }
72 }
73
74 APPSPAWN_CHECK(g_decPolicyInfos->pathNum + decPolicyInfos->pathNum <= MAX_POLICY_NUM,
75 DestroyDecPolicyInfos(g_decPolicyInfos);
76 g_decPolicyInfos = NULL;
77 return, "Out of MAX_POLICY_NUM %{public}d, %{public}d", g_decPolicyInfos->pathNum, decPolicyInfos->pathNum);
78 for (uint32_t i = 0; i < decPolicyInfos->pathNum; i++) {
79 PathInfo pathInfo = {0};
80 if (decPolicyInfos->path[i].path == NULL) {
81 DestroyDecPolicyInfos(g_decPolicyInfos);
82 g_decPolicyInfos = NULL;
83 return;
84 }
85 pathInfo.path = strdup(decPolicyInfos->path[i].path);
86 if (pathInfo.path == NULL) {
87 DestroyDecPolicyInfos(g_decPolicyInfos);
88 g_decPolicyInfos = NULL;
89 return;
90 }
91 pathInfo.pathLen = (uint32_t)strlen(pathInfo.path);
92 pathInfo.mode = decPolicyInfos->path[i].mode;
93 uint32_t index = g_decPolicyInfos->pathNum + i;
94 g_decPolicyInfos->path[index] = pathInfo;
95 }
96 g_decPolicyInfos->tokenId = decPolicyInfos->tokenId;
97 g_decPolicyInfos->pathNum += decPolicyInfos->pathNum;
98 g_decPolicyInfos->flag = true;
99 g_decPolicyInfos->userId = 0;
100 }
101
SetDenyConstraintDirs(AppSpawnMgr * content)102 static int SetDenyConstraintDirs(AppSpawnMgr *content)
103 {
104 APPSPAWN_LOGI("enter SetDenyConstraintDirs sandbox policy success.");
105 UNUSED(content);
106 const char *decFilename = "/dev/dec";
107 int fd = open(decFilename, O_RDWR);
108 if (fd < 0) {
109 APPSPAWN_LOGE("open dec file fail.");
110 return 0;
111 }
112
113 uint32_t decDirsSize = ARRAY_LENGTH(g_decConstraintDir);
114 DecPolicyInfo decPolicyInfos = {0};
115 decPolicyInfos.tokenId = 0;
116 decPolicyInfos.pathNum = decDirsSize;
117 decPolicyInfos.flag = 0;
118
119 for (uint32_t i = 0; i < decDirsSize; i++) {
120 PathInfo pathInfo = {(char *)g_decConstraintDir[i], (uint32_t)strlen(g_decConstraintDir[i]), SANDBOX_MODE_READ};
121 decPolicyInfos.path[i] = pathInfo;
122 }
123
124 if (ioctl(fd, CONSTRAINT_DEC_POLICY_CMD, &decPolicyInfos) < 0) {
125 APPSPAWN_LOGE("set sandbox policy failed.");
126 } else {
127 APPSPAWN_LOGI("set CONSTRAINT_DEC_POLICY_CMD sandbox policy success.");
128 for (uint32_t i = 0; i < decPolicyInfos.pathNum; i++) {
129 APPSPAWN_LOGI("policy info: %{public}s", decPolicyInfos.path[i].path);
130 }
131 }
132 close(fd);
133 return 0;
134 }
135
SetForcedPrefixDirs(AppSpawnMgr * content)136 static int SetForcedPrefixDirs(AppSpawnMgr *content)
137 {
138 APPSPAWN_LOGI("enter SetForcedPrefixDirs sandbox policy success.");
139 UNUSED(content);
140 const char *decFilename = "/dev/dec";
141 int fd = open(decFilename, O_RDWR);
142 if (fd < 0) {
143 APPSPAWN_LOGE("open dec file fail.");
144 return 0;
145 }
146
147 uint32_t decDirsSize = ARRAY_LENGTH(g_decForcedPrefix);
148 DecPolicyInfo decPolicyInfos = {0};
149 decPolicyInfos.tokenId = 0;
150 decPolicyInfos.pathNum = decDirsSize;
151 decPolicyInfos.flag = 0;
152
153 for (uint32_t i = 0; i < decDirsSize; i++) {
154 PathInfo pathInfo = {(char *)g_decForcedPrefix[i], (uint32_t)strlen(g_decForcedPrefix[i]), SANDBOX_MODE_READ};
155 decPolicyInfos.path[i] = pathInfo;
156 }
157
158 if (ioctl(fd, SET_DEC_PREFIX_CMD, &decPolicyInfos) < 0) {
159 APPSPAWN_LOGE("set sandbox forced prefix failed.");
160 } else {
161 APPSPAWN_LOGI("set SET_DEC_PREFIX_CMD sandbox policy success.");
162 for (uint32_t i = 0; i < decPolicyInfos.pathNum; i++) {
163 APPSPAWN_LOGI("policy info: %{public}s", decPolicyInfos.path[i].path);
164 }
165 }
166 close(fd);
167 return 0;
168 }
169
SetDecPolicy(void)170 void SetDecPolicy(void)
171 {
172 if (g_decPolicyInfos == NULL) {
173 return;
174 }
175 const char *decFilename = "/dev/dec";
176 int fd = open(decFilename, O_RDWR);
177 if (fd < 0) {
178 APPSPAWN_LOGE("open dec file fail.");
179 DestroyDecPolicyInfos(g_decPolicyInfos);
180 g_decPolicyInfos = NULL;
181 return;
182 }
183
184 struct timespec ts;
185 clock_gettime(CLOCK_MONOTONIC, &ts);
186 uint64_t timestamp = ts.tv_sec * APPSPAWN_SEC_TO_NSEC + ts.tv_nsec;
187 g_decPolicyInfos->timestamp = timestamp;
188
189 if (ioctl(fd, SET_DEC_POLICY_CMD, g_decPolicyInfos) < 0) {
190 APPSPAWN_LOGE("set sandbox policy failed.");
191 } else {
192 APPSPAWN_LOGI("set SET_DEC_POLICY_CMD sandbox policy success. timestamp:%{public}" PRId64 "", timestamp);
193 for (uint32_t i = 0; i < g_decPolicyInfos->pathNum; i++) {
194 APPSPAWN_LOGI("policy info: path %{public}s, mode 0x%{public}x",
195 g_decPolicyInfos->path[i].path, g_decPolicyInfos->path[i].mode);
196 }
197 }
198 close(fd);
199 DestroyDecPolicyInfos(g_decPolicyInfos);
200 g_decPolicyInfos = NULL;
201 return;
202 }
203
MODULE_CONSTRUCTOR(void)204 MODULE_CONSTRUCTOR(void)
205 {
206 APPSPAWN_LOGI("Load sandbox dec module ...");
207 AddPreloadHook(HOOK_PRIO_COMMON, SetDenyConstraintDirs);
208 AddPreloadHook(HOOK_PRIO_COMMON, SetForcedPrefixDirs);
209 }
210