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 "app_spawn_stub.h"
17
18#include <errno.h>
19#include <fcntl.h>
20#include <linux/capability.h>
21#include <pthread.h>
22#include <pwd.h>
23#include <signal.h>
24#include <stdarg.h>
25#include <stdbool.h>
26#include <stdlib.h>
27#include <time.h>
28#include <unistd.h>
29
30#include <sys/socket.h>
31#include <sys/stat.h>
32#include <sys/time.h>
33#include <sys/types.h>
34#include <sys/un.h>
35#include <sys/wait.h>
36
37#include "appspawn_hook.h"
38#include "appspawn_server.h"
39#include "appspawn_sandbox.h"
40#include "hilog/log.h"
41#include "securec.h"
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47StubNode g_stubNodes[] = {
48    {STUB_MOUNT, 0, 0, NULL},
49    {STUB_EXECV, 0, 0, NULL},
50};
51
52StubNode *GetStubNode(int type)
53{
54    if (type >= (int)(sizeof(g_stubNodes) / sizeof(g_stubNodes[0]))) {
55        return NULL;
56    }
57
58    return &g_stubNodes[type];
59}
60
61void *DlopenStub(const char *pathname, int mode)
62{
63    UNUSED(pathname);
64    UNUSED(mode);
65    static size_t index = 0;
66    return &index;
67}
68
69static bool InitEnvironmentParamStub(const char *name)
70{
71    UNUSED(name);
72    return true;
73}
74
75static bool SetRendererSecCompPolicyStub(void)
76{
77    return true;
78}
79
80static void NWebRenderMainStub(const char *cmd)
81{
82    printf("NWebRenderMainStub cmd %s \n", cmd);
83}
84
85uint32_t g_dlsymResultFlags = 0;
86#define DLSYM_FAIL_SET_SEC_POLICY 0x01
87#define DLSYM_FAIL_NWEB_MAIN 0x02
88#define DLSYM_FAIL_INIT_ENV 0x04
89void SetDlsymResult(uint32_t flags, bool success)
90{
91    if (success) {
92        g_dlsymResultFlags &= ~flags;
93    } else {
94        g_dlsymResultFlags |= flags;
95    }
96}
97
98void *DlsymStub(void *handle, const char *symbol)
99{
100    printf("DlsymStub %s \n", symbol);
101    UNUSED(handle);
102    if (strcmp(symbol, "InitEnvironmentParam") == 0) {
103        return ((g_dlsymResultFlags & DLSYM_FAIL_INIT_ENV) == 0) ? (void *)(InitEnvironmentParamStub) : NULL;
104    }
105    if (strcmp(symbol, "SetRendererSeccompPolicy") == 0) {
106        return ((g_dlsymResultFlags & DLSYM_FAIL_SET_SEC_POLICY) == 0) ? (void *)(SetRendererSecCompPolicyStub) : NULL;
107    }
108    if (strcmp(symbol, "NWebRenderMain") == 0) {
109        return ((g_dlsymResultFlags & DLSYM_FAIL_NWEB_MAIN) == 0) ? (void *)(NWebRenderMainStub) : NULL;
110    }
111    return NULL;
112}
113
114int DlcloseStub(void *handle)
115{
116    UNUSED(handle);
117    return 0;
118}
119
120void DisallowInternet(void)
121{
122}
123
124bool may_init_gwp_asan(bool forceInit)
125{
126    return false;
127}
128
129int SetgroupsStub(size_t size, const gid_t *list)
130{
131    UNUSED(size);
132    UNUSED(list);
133    return 0;
134}
135
136int SetresuidStub(uid_t ruid, uid_t euid, uid_t suid)
137{
138    UNUSED(ruid);
139    UNUSED(euid);
140    UNUSED(suid);
141    return 0;
142}
143
144int SetresgidStub(gid_t rgid, gid_t egid, gid_t sgid)
145{
146    UNUSED(rgid);
147    UNUSED(egid);
148    UNUSED(sgid);
149    return 0;
150}
151
152int CapsetStub(cap_user_header_t hdrp, const cap_user_data_t datap)
153{
154    UNUSED(hdrp);
155    UNUSED(datap);
156    return 0;
157}
158
159int UnshareStub(int flags)
160{
161    printf("UnshareStub %x \n", flags);
162    return 0;
163}
164
165int MountStub(const char *originPath, const char *destinationPath,
166    const char *fsType, unsigned long mountFlags, const char *options, mode_t mountSharedFlag)
167{
168    StubNode *node = GetStubNode(STUB_MOUNT);
169    if (node == NULL || node->arg == NULL || (node->flags & STUB_NEED_CHECK) != STUB_NEED_CHECK) {
170        return 0;
171    }
172    MountArg *args = (MountArg *)node->arg;
173
174    printf("args->originPath %s == %s \n", args->originPath, originPath);
175    printf("args->destinationPath %s == %s \n", args->destinationPath, destinationPath);
176    printf("args->fsType %s == %s \n", args->fsType, fsType);
177    printf("args->options %s == %s \n", args->options, options);
178    printf("mountFlags %lx args->mountFlags %lx \n", mountFlags, args->mountFlags);
179    printf("mountSharedFlag 0x%x args->mountSharedFlag 0x%x \n", mountSharedFlag, args->mountSharedFlag);
180
181    if (originPath != NULL && (strcmp(originPath, args->originPath) == 0)) {
182        int result = (destinationPath != NULL && (strcmp(destinationPath, args->destinationPath) == 0) &&
183            (mountFlags == args->mountFlags) &&
184            (args->fsType == NULL || (fsType != NULL && strcmp(fsType, args->fsType) == 0)) &&
185            (args->options == NULL || (options != NULL && strcmp(options, args->options) == 0)));
186        errno = result ? 0 : -EINVAL;
187        node->result = result ? 0 : -EINVAL;
188        printf("MountStub result %d node->result %d \n", result, node->result);
189        return errno;
190    }
191    return 0;
192}
193
194int SymlinkStub(const char *target, const char *linkName)
195{
196    return 0;
197}
198
199int ChdirStub(const char *path)
200{
201    return 0;
202}
203
204int ChrootStub(const char *path)
205{
206    return 0;
207}
208
209long int SyscallStub(long int type, ...)
210{
211    return 0;
212}
213
214int Umount2Stub(const char *path, int type)
215{
216    return 0;
217}
218
219int UmountStub(const char *path)
220{
221    return 0;
222}
223
224int mallopt(int param, int value)
225{
226    return 0;
227}
228
229int AccessStub(const char *pathName, int mode)
230{
231    if (strstr(pathName, "/data/app/el2/50/base") != NULL) {
232        return -1;
233    }
234    if (strstr(pathName, "/mnt/sandbox/50/com.example.myapplication/data/storage/el2") != NULL) {
235        return -1;
236    }
237    if (strstr(pathName, "/data/app/el5/100/base/com.example.myapplication") != NULL) {
238        return -1;
239    }
240    return 0;
241}
242
243int ExecvStub(const char *pathName, char *const argv[])
244{
245    printf("ExecvStub %s \n", pathName);
246    StubNode *node = GetStubNode(STUB_EXECV);
247    if (node == NULL || node->arg == NULL || (node->flags & STUB_NEED_CHECK) != STUB_NEED_CHECK) {
248        return 0;
249    }
250
251    ExecvFunc func = (ExecvFunc)node->arg;
252    func(pathName, argv);
253    return 0;
254}
255
256int ExecvpStub(const char *pathName, char *const argv[])
257{
258    printf("ExecvpStub %s \n", pathName);
259    return 0;
260}
261
262int ExecveStub(const char *pathName, char *const argv[], char *const env[])
263{
264    printf("ExecveStub %s \n", pathName);
265    return 0;
266}
267
268int SetconStub(const char *name)
269{
270    printf("SetconStub %s \n", name);
271    return 0;
272}
273
274int GetprocpidStub()
275{
276    return 0;
277}
278
279int CloneStub(int (*fn)(void *), void *stack, int flags, void *arg, ...)
280{
281    printf("CloneStub 11 %d \n", getpid());
282    pid_t pid = fork();
283    if (pid == 0) {
284        fn(arg);
285        _exit(0x7f); // 0x7f user exit
286    }
287    return pid;
288}
289
290int SetuidStub(uid_t uid)
291{
292    return 0;
293}
294
295int SetgidStub(gid_t gid)
296{
297    return 0;
298}
299
300int IoctlStub(int fd, unsigned long request, ...)
301{
302    return 0;
303}
304
305#ifdef __cplusplus
306}
307#endif
308