• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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