1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci*/
15cc290419Sopenharmony_ci
16cc290419Sopenharmony_ci#include <termios.h>
17cc290419Sopenharmony_ci#include <cstring>
18cc290419Sopenharmony_ci#include <unistd.h>
19cc290419Sopenharmony_ci#include <climits>
20cc290419Sopenharmony_ci#include <sys/types.h>
21cc290419Sopenharmony_ci#include <sys/wait.h>
22cc290419Sopenharmony_ci#include <sys/stat.h>
23cc290419Sopenharmony_ci#include <securec.h>
24cc290419Sopenharmony_ci
25cc290419Sopenharmony_ci#if defined(SURPPORT_SELINUX)
26cc290419Sopenharmony_ci#include "selinux/selinux.h"
27cc290419Sopenharmony_ci#endif
28cc290419Sopenharmony_ci#include "account_iam_client.h"
29cc290419Sopenharmony_ci#include "os_account_manager.h"
30cc290419Sopenharmony_ci#include "sudo_iam.h"
31cc290419Sopenharmony_ci
32cc290419Sopenharmony_ci#define PWD_BUF_LEN 128
33cc290419Sopenharmony_ci#define DEFAULT_PATH "/system/bin"
34cc290419Sopenharmony_ci#define DEFAULT_BASH "/system/bin/sh"
35cc290419Sopenharmony_ci
36cc290419Sopenharmony_ciusing namespace OHOS::UserIam;
37cc290419Sopenharmony_ciusing namespace OHOS::AccountSA;
38cc290419Sopenharmony_ci
39cc290419Sopenharmony_cistatic FILE *g_ttyFp = nullptr;
40cc290419Sopenharmony_ci
41cc290419Sopenharmony_cistatic const char *OUT_OF_MEM = "[E0001] out of memory\n";
42cc290419Sopenharmony_cistatic const char *COMMAND_NOT_FOUND = "[E0002] command not found\n";
43cc290419Sopenharmony_cistatic const char *USER_VERIFY_FAILED = "[E0003] Sorry, try again. If screen lock password not set, set it first.\n";
44cc290419Sopenharmony_ci
45cc290419Sopenharmony_cistatic void WriteStdErr(const char *str)
46cc290419Sopenharmony_ci{
47cc290419Sopenharmony_ci    (void)fwrite(str, 1, strlen(str), stderr);
48cc290419Sopenharmony_ci    fflush(stderr);
49cc290419Sopenharmony_ci}
50cc290419Sopenharmony_ci
51cc290419Sopenharmony_cistatic void WriteTty(const char *str)
52cc290419Sopenharmony_ci{
53cc290419Sopenharmony_ci    if (g_ttyFp != nullptr) {
54cc290419Sopenharmony_ci        (void)fwrite(str, 1, strlen(str), g_ttyFp);
55cc290419Sopenharmony_ci        fflush(g_ttyFp);
56cc290419Sopenharmony_ci    } else {
57cc290419Sopenharmony_ci        g_ttyFp = fopen("/dev/tty", "w");
58cc290419Sopenharmony_ci        if (g_ttyFp != nullptr) {
59cc290419Sopenharmony_ci            (void)fwrite(str, 1, strlen(str), g_ttyFp);
60cc290419Sopenharmony_ci            fflush(g_ttyFp);
61cc290419Sopenharmony_ci            return;
62cc290419Sopenharmony_ci        }
63cc290419Sopenharmony_ci        WriteStdErr("open /dev/tty for write failed\n");
64cc290419Sopenharmony_ci    }
65cc290419Sopenharmony_ci}
66cc290419Sopenharmony_ci
67cc290419Sopenharmony_cistatic void CloseTty(void)
68cc290419Sopenharmony_ci{
69cc290419Sopenharmony_ci    if (g_ttyFp != nullptr) {
70cc290419Sopenharmony_ci        fclose(g_ttyFp);
71cc290419Sopenharmony_ci    }
72cc290419Sopenharmony_ci    g_ttyFp = nullptr;
73cc290419Sopenharmony_ci}
74cc290419Sopenharmony_ci
75cc290419Sopenharmony_cistatic char *StrDup(const char *str)
76cc290419Sopenharmony_ci{
77cc290419Sopenharmony_ci    int ret;
78cc290419Sopenharmony_ci    char *result = new(std::nothrow)char[strlen(str) + 1];
79cc290419Sopenharmony_ci    if (result == nullptr) {
80cc290419Sopenharmony_ci        WriteStdErr(OUT_OF_MEM);
81cc290419Sopenharmony_ci        exit(1);
82cc290419Sopenharmony_ci    }
83cc290419Sopenharmony_ci    ret = strcpy_s(result, strlen(str) + 1, str);
84cc290419Sopenharmony_ci    if (ret != 0) {
85cc290419Sopenharmony_ci        WriteStdErr(OUT_OF_MEM);
86cc290419Sopenharmony_ci        exit(1);
87cc290419Sopenharmony_ci    }
88cc290419Sopenharmony_ci    return result;
89cc290419Sopenharmony_ci}
90cc290419Sopenharmony_ci
91cc290419Sopenharmony_cistatic void FreeArgvNew(char **argvNew)
92cc290419Sopenharmony_ci{
93cc290419Sopenharmony_ci    char **p = nullptr;
94cc290419Sopenharmony_ci    for (p = argvNew; *p != nullptr; p++) {
95cc290419Sopenharmony_ci        delete [] *p;
96cc290419Sopenharmony_ci    }
97cc290419Sopenharmony_ci    delete [] argvNew;
98cc290419Sopenharmony_ci}
99cc290419Sopenharmony_ci
100cc290419Sopenharmony_ci/*
101cc290419Sopenharmony_ci * Find cmd from PATH
102cc290419Sopenharmony_ci*/
103cc290419Sopenharmony_cistatic bool GetCmdInPath(char *cmd, int cmdBufLen, char *envp[])
104cc290419Sopenharmony_ci{
105cc290419Sopenharmony_ci    struct stat st;
106cc290419Sopenharmony_ci    char *path = nullptr;
107cc290419Sopenharmony_ci    char *pathBak = nullptr;
108cc290419Sopenharmony_ci    char **ep = nullptr;
109cc290419Sopenharmony_ci    char *cp = nullptr;
110cc290419Sopenharmony_ci    char pathBuf[PATH_MAX + 1] = {0};
111cc290419Sopenharmony_ci    bool findSuccess = false;
112cc290419Sopenharmony_ci
113cc290419Sopenharmony_ci    if (strchr(cmd, '/') != nullptr) {
114cc290419Sopenharmony_ci        return true;
115cc290419Sopenharmony_ci    }
116cc290419Sopenharmony_ci
117cc290419Sopenharmony_ci    for (ep = envp; *ep != nullptr; ep++) {
118cc290419Sopenharmony_ci        if (strcmp(*ep, "PATH=") == 0) {
119cc290419Sopenharmony_ci            path = *ep + strlen("PATH=");
120cc290419Sopenharmony_ci            break;
121cc290419Sopenharmony_ci        }
122cc290419Sopenharmony_ci    }
123cc290419Sopenharmony_ci
124cc290419Sopenharmony_ci    path = StrDup((path != nullptr && *path != '\0') ? path : DEFAULT_PATH);
125cc290419Sopenharmony_ci    pathBak = path;
126cc290419Sopenharmony_ci    do {
127cc290419Sopenharmony_ci        if ((cp = strchr(path, ':')) != nullptr) {
128cc290419Sopenharmony_ci            *cp = '\0';
129cc290419Sopenharmony_ci        }
130cc290419Sopenharmony_ci        int ret = sprintf_s(pathBuf, sizeof(pathBuf), "%s/%s", *path ? path : ".", cmd);
131cc290419Sopenharmony_ci        if (ret > 0 && stat(pathBuf, &st) == 0 && S_ISREG(st.st_mode)) {
132cc290419Sopenharmony_ci            findSuccess = true;
133cc290419Sopenharmony_ci            break;
134cc290419Sopenharmony_ci        }
135cc290419Sopenharmony_ci        path = cp + 1;
136cc290419Sopenharmony_ci    } while (cp != nullptr);
137cc290419Sopenharmony_ci
138cc290419Sopenharmony_ci    free(pathBak);
139cc290419Sopenharmony_ci    if (!findSuccess) {
140cc290419Sopenharmony_ci        WriteTty(COMMAND_NOT_FOUND);
141cc290419Sopenharmony_ci        return false;
142cc290419Sopenharmony_ci    }
143cc290419Sopenharmony_ci    return (sprintf_s(cmd, cmdBufLen, "%s", pathBuf) < 0) ? false : true;
144cc290419Sopenharmony_ci}
145cc290419Sopenharmony_ci
146cc290419Sopenharmony_cistatic char **ParseCmd(int argc, char* argv[], char* env[], char *cmd, int cmdLen)
147cc290419Sopenharmony_ci{
148cc290419Sopenharmony_ci    int startCopyArgvIndex = 1;
149cc290419Sopenharmony_ci    int argvNewIndex = 0;
150cc290419Sopenharmony_ci    char **argvTmp = nullptr;
151cc290419Sopenharmony_ci    bool isShc = false;
152cc290419Sopenharmony_ci    int ret;
153cc290419Sopenharmony_ci
154cc290419Sopenharmony_ci    /*
155cc290419Sopenharmony_ci     * Here, we construct the command and its argv
156cc290419Sopenharmony_ci     * sudo sh -c xxx yyy -----> sh -c xxx yyy
157cc290419Sopenharmony_ci     * sudo xxx yyy       -----> xxx yyy
158cc290419Sopenharmony_ci    */
159cc290419Sopenharmony_ci    if (argc <= 0) {
160cc290419Sopenharmony_ci        return nullptr;
161cc290419Sopenharmony_ci    }
162cc290419Sopenharmony_ci    argvTmp = new(std::nothrow) char* [argc];
163cc290419Sopenharmony_ci    if (argvTmp == nullptr) {
164cc290419Sopenharmony_ci        WriteStdErr(OUT_OF_MEM);
165cc290419Sopenharmony_ci        return nullptr;
166cc290419Sopenharmony_ci    }
167cc290419Sopenharmony_ci    (void)memset_s(argvTmp, sizeof(char*) * argc, 0, sizeof(char*) * argc);
168cc290419Sopenharmony_ci    /*
169cc290419Sopenharmony_ci     * sudo sh -c xxxx
170cc290419Sopenharmony_ci    */
171cc290419Sopenharmony_ci    if (argc >= 3) { //3:argc of main
172cc290419Sopenharmony_ci        if (strcmp(argv[1], "sh") == 0 && strcmp(argv[2], "-c") == 0) { //2:argv 2 of main
173cc290419Sopenharmony_ci            // argvNew[0] is "/system/bin/sh"
174cc290419Sopenharmony_ci            argvTmp[argvNewIndex++] = StrDup(DEFAULT_BASH);
175cc290419Sopenharmony_ci            // argvNew[1] is "-c"
176cc290419Sopenharmony_ci            argvTmp[argvNewIndex++] = StrDup("-c");
177cc290419Sopenharmony_ci            ret = sprintf_s(cmd, cmdLen, "%s", DEFAULT_BASH);
178cc290419Sopenharmony_ci            if (ret < 0) {
179cc290419Sopenharmony_ci                FreeArgvNew(argvTmp);
180cc290419Sopenharmony_ci                return nullptr;
181cc290419Sopenharmony_ci            }
182cc290419Sopenharmony_ci            startCopyArgvIndex = 3; //3:start copy index of argv
183cc290419Sopenharmony_ci            isShc = true;
184cc290419Sopenharmony_ci        }
185cc290419Sopenharmony_ci    }
186cc290419Sopenharmony_ci
187cc290419Sopenharmony_ci    /*
188cc290419Sopenharmony_ci     * if not "sudo sh -c xxxx", just as "sudo xxxx"
189cc290419Sopenharmony_ci    */
190cc290419Sopenharmony_ci    if (!isShc) {
191cc290419Sopenharmony_ci        ret = sprintf_s(cmd, cmdLen, "%s", argv[1]);
192cc290419Sopenharmony_ci        if (ret < 0 || !GetCmdInPath(cmd, cmdLen, env)) {
193cc290419Sopenharmony_ci            FreeArgvNew(argvTmp);
194cc290419Sopenharmony_ci            return nullptr;
195cc290419Sopenharmony_ci        }
196cc290419Sopenharmony_ci        argvTmp[argvNewIndex++] = StrDup(cmd);
197cc290419Sopenharmony_ci        startCopyArgvIndex = 2; //2:start copy index of argv
198cc290419Sopenharmony_ci    }
199cc290419Sopenharmony_ci
200cc290419Sopenharmony_ci    for (int i = startCopyArgvIndex; i < argc; i++) {
201cc290419Sopenharmony_ci        argvTmp[argvNewIndex++] = StrDup(argv[i]);
202cc290419Sopenharmony_ci    }
203cc290419Sopenharmony_ci    argvTmp[argvNewIndex] = nullptr;
204cc290419Sopenharmony_ci
205cc290419Sopenharmony_ci    return argvTmp;
206cc290419Sopenharmony_ci}
207cc290419Sopenharmony_ci
208cc290419Sopenharmony_cistatic void GetUserPwd(char *pwdBuf, int bufLen)
209cc290419Sopenharmony_ci{
210cc290419Sopenharmony_ci    const char *prompts = "[sudo] password for current user:";
211cc290419Sopenharmony_ci    const char *newline = "\n";
212cc290419Sopenharmony_ci    struct termios oldTerm;
213cc290419Sopenharmony_ci    struct termios newTerm;
214cc290419Sopenharmony_ci
215cc290419Sopenharmony_ci    WriteTty(prompts);
216cc290419Sopenharmony_ci
217cc290419Sopenharmony_ci    tcgetattr(STDIN_FILENO, &oldTerm);
218cc290419Sopenharmony_ci    newTerm = oldTerm;
219cc290419Sopenharmony_ci    newTerm.c_lflag &= ~(ECHO);
220cc290419Sopenharmony_ci    tcsetattr(STDIN_FILENO, TCSANOW, &newTerm);
221cc290419Sopenharmony_ci    (void)fgets(pwdBuf, bufLen, stdin);
222cc290419Sopenharmony_ci    if (pwdBuf[strlen(pwdBuf) - 1] == '\n') {
223cc290419Sopenharmony_ci        pwdBuf[strlen(pwdBuf) - 1] = '\0';
224cc290419Sopenharmony_ci    }
225cc290419Sopenharmony_ci    tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
226cc290419Sopenharmony_ci
227cc290419Sopenharmony_ci    WriteTty(newline);
228cc290419Sopenharmony_ci}
229cc290419Sopenharmony_ci
230cc290419Sopenharmony_cistatic bool SetUidGid(void)
231cc290419Sopenharmony_ci{
232cc290419Sopenharmony_ci    if (setuid(0) != 0) {
233cc290419Sopenharmony_ci        return false;
234cc290419Sopenharmony_ci    }
235cc290419Sopenharmony_ci    if (setegid(0) != 0) {
236cc290419Sopenharmony_ci        return false;
237cc290419Sopenharmony_ci    }
238cc290419Sopenharmony_ci    if (setgid(0) != 0) {
239cc290419Sopenharmony_ci        return false;
240cc290419Sopenharmony_ci    }
241cc290419Sopenharmony_ci    return true;
242cc290419Sopenharmony_ci}
243cc290419Sopenharmony_ci
244cc290419Sopenharmony_cistatic void WaitForAuth(void)
245cc290419Sopenharmony_ci{
246cc290419Sopenharmony_ci    std::unique_lock<std::mutex> lock(g_mutexForAuth);
247cc290419Sopenharmony_ci    g_condVarForAuth.wait(lock, [] { return g_authFinish; });
248cc290419Sopenharmony_ci}
249cc290419Sopenharmony_ci
250cc290419Sopenharmony_cistatic bool VerifyAccount(int32_t userId)
251cc290419Sopenharmony_ci{
252cc290419Sopenharmony_ci    std::vector<uint8_t> challenge;
253cc290419Sopenharmony_ci    AuthOptions authOptions;
254cc290419Sopenharmony_ci    bool verifyResult = false;
255cc290419Sopenharmony_ci
256cc290419Sopenharmony_ci    AccountIAMClient &sudoIAMClient = AccountIAMClient::GetInstance();
257cc290419Sopenharmony_ci    std::shared_ptr<IDMCallback> callback = std::make_shared<SudoIDMCallback>();
258cc290419Sopenharmony_ci    authOptions.accountId = userId;
259cc290419Sopenharmony_ci    sudoIAMClient.AuthUser(authOptions, challenge, AuthType::PIN, AuthTrustLevel::ATL1, callback);
260cc290419Sopenharmony_ci    std::shared_ptr<SudoIDMCallback> sudoCallback = std::static_pointer_cast<SudoIDMCallback>(callback);
261cc290419Sopenharmony_ci    WaitForAuth();
262cc290419Sopenharmony_ci    verifyResult = sudoCallback->GetVerifyResult();
263cc290419Sopenharmony_ci    return verifyResult;
264cc290419Sopenharmony_ci}
265cc290419Sopenharmony_ci
266cc290419Sopenharmony_cistatic bool UserAccountVerify(char *pwd, int pwdLen)
267cc290419Sopenharmony_ci{
268cc290419Sopenharmony_ci    std::shared_ptr<PinAuth::IInputer> inputer = nullptr;
269cc290419Sopenharmony_ci    OHOS::ErrCode err;
270cc290419Sopenharmony_ci    int verifyResult = 0;
271cc290419Sopenharmony_ci    pid_t pid;
272cc290419Sopenharmony_ci    int fds[2];
273cc290419Sopenharmony_ci
274cc290419Sopenharmony_ci    if (pipe(fds) != 0) {
275cc290419Sopenharmony_ci        WriteStdErr("exec pipe failed\n");
276cc290419Sopenharmony_ci        return false;
277cc290419Sopenharmony_ci    }
278cc290419Sopenharmony_ci    pid = fork();
279cc290419Sopenharmony_ci    if (pid == -1) {
280cc290419Sopenharmony_ci        WriteStdErr("exec fork failed\n");
281cc290419Sopenharmony_ci        return false;
282cc290419Sopenharmony_ci    }
283cc290419Sopenharmony_ci    if (pid == 0) {
284cc290419Sopenharmony_ci        int32_t userId = -1;
285cc290419Sopenharmony_ci        close(fds[0]);
286cc290419Sopenharmony_ci        err = OsAccountManager::GetForegroundOsAccountLocalId(userId);
287cc290419Sopenharmony_ci        if (err != 0) {
288cc290419Sopenharmony_ci            WriteStdErr("get os account local id failed\n");
289cc290419Sopenharmony_ci            exit(1);
290cc290419Sopenharmony_ci        }
291cc290419Sopenharmony_ci        inputer = std::make_shared<PinAuth::SudoIInputer>();
292cc290419Sopenharmony_ci        std::shared_ptr<PinAuth::SudoIInputer> sudoInputer = std::static_pointer_cast<PinAuth::SudoIInputer>(inputer);
293cc290419Sopenharmony_ci        sudoInputer->SetPasswd(pwd, pwdLen);
294cc290419Sopenharmony_ci        err = AccountIAMClient::GetInstance().RegisterPINInputer(inputer);
295cc290419Sopenharmony_ci        if (err != 0) {
296cc290419Sopenharmony_ci            WriteStdErr("register pin inputer failed\n");
297cc290419Sopenharmony_ci            exit(1);
298cc290419Sopenharmony_ci        }
299cc290419Sopenharmony_ci        if (VerifyAccount(userId)) {
300cc290419Sopenharmony_ci            verifyResult = 1;
301cc290419Sopenharmony_ci        }
302cc290419Sopenharmony_ci        AccountIAMClient::GetInstance().UnregisterPINInputer();
303cc290419Sopenharmony_ci        write(fds[1], &verifyResult, sizeof(verifyResult));
304cc290419Sopenharmony_ci        close(fds[1]);
305cc290419Sopenharmony_ci        exit(0);
306cc290419Sopenharmony_ci    } else {
307cc290419Sopenharmony_ci        close(fds[1]);
308cc290419Sopenharmony_ci        waitpid(pid, nullptr, 0);
309cc290419Sopenharmony_ci        read(fds[0], &verifyResult, sizeof(verifyResult));
310cc290419Sopenharmony_ci        close(fds[0]);
311cc290419Sopenharmony_ci        return (verifyResult == 1);
312cc290419Sopenharmony_ci    }
313cc290419Sopenharmony_ci}
314cc290419Sopenharmony_ci
315cc290419Sopenharmony_cistatic bool VerifyUserPin(void)
316cc290419Sopenharmony_ci{
317cc290419Sopenharmony_ci    char passwd[PWD_BUF_LEN] = {0};
318cc290419Sopenharmony_ci    bool pwdVerifyResult = false;
319cc290419Sopenharmony_ci
320cc290419Sopenharmony_ci    if (getuid() == 0) {
321cc290419Sopenharmony_ci        return true;
322cc290419Sopenharmony_ci    }
323cc290419Sopenharmony_ci
324cc290419Sopenharmony_ci    GetUserPwd(passwd, PWD_BUF_LEN);
325cc290419Sopenharmony_ci    pwdVerifyResult = UserAccountVerify(passwd, strnlen(passwd, PWD_BUF_LEN));
326cc290419Sopenharmony_ci    memset_s(passwd, sizeof(passwd), 0, sizeof(passwd));
327cc290419Sopenharmony_ci    if (!pwdVerifyResult) {
328cc290419Sopenharmony_ci        WriteTty(USER_VERIFY_FAILED);
329cc290419Sopenharmony_ci    }
330cc290419Sopenharmony_ci    return pwdVerifyResult;
331cc290419Sopenharmony_ci}
332cc290419Sopenharmony_ci
333cc290419Sopenharmony_ciint main(int argc, char* argv[], char* env[])
334cc290419Sopenharmony_ci{
335cc290419Sopenharmony_ci    char execCmd[PATH_MAX + 1] = {0};
336cc290419Sopenharmony_ci    char **argvNew = nullptr;
337cc290419Sopenharmony_ci    const char *help = "sudo - execute command as root\n\n"
338cc290419Sopenharmony_ci                       "usage: sudo command ...\n"
339cc290419Sopenharmony_ci                       "usage: sudo sh -c command ...\n";
340cc290419Sopenharmony_ci    if (argc < 2) { //2:argc check number
341cc290419Sopenharmony_ci        WriteStdErr(help);
342cc290419Sopenharmony_ci        return 1;
343cc290419Sopenharmony_ci    }
344cc290419Sopenharmony_ci
345cc290419Sopenharmony_ci    /*
346cc290419Sopenharmony_ci     * Get and verify user pwd
347cc290419Sopenharmony_ci    */
348cc290419Sopenharmony_ci    if (!VerifyUserPin()) {
349cc290419Sopenharmony_ci        return 1;
350cc290419Sopenharmony_ci    }
351cc290419Sopenharmony_ci
352cc290419Sopenharmony_ci    /*
353cc290419Sopenharmony_ci     * Make exec cmd and the args
354cc290419Sopenharmony_ci    */
355cc290419Sopenharmony_ci    argvNew = ParseCmd(argc, argv, env, execCmd, PATH_MAX + 1);
356cc290419Sopenharmony_ci    if (argvNew == nullptr) {
357cc290419Sopenharmony_ci        return 1;
358cc290419Sopenharmony_ci    }
359cc290419Sopenharmony_ci    CloseTty();
360cc290419Sopenharmony_ci
361cc290419Sopenharmony_ci    /*
362cc290419Sopenharmony_ci     * set uid, gid, egid
363cc290419Sopenharmony_ci    */
364cc290419Sopenharmony_ci    if (!SetUidGid()) {
365cc290419Sopenharmony_ci        FreeArgvNew(argvNew);
366cc290419Sopenharmony_ci        WriteStdErr("setuid failed\n");
367cc290419Sopenharmony_ci        return 1;
368cc290419Sopenharmony_ci    }
369cc290419Sopenharmony_ci
370cc290419Sopenharmony_ci#if defined(SURPPORT_SELINUX)
371cc290419Sopenharmony_ci    setcon("u:r:privilege_app:s0");
372cc290419Sopenharmony_ci#endif
373cc290419Sopenharmony_ci
374cc290419Sopenharmony_ci    execvp(execCmd, argvNew);
375cc290419Sopenharmony_ci
376cc290419Sopenharmony_ci    WriteStdErr("execvp failed\n");
377cc290419Sopenharmony_ci    return 1;
378cc290419Sopenharmony_ci}
379