• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
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 "common.h"
17 #include <fcntl.h>
18 #include <array>
19 #include <cinttypes>
20 #include <csignal>
21 #include <dirent.h>
22 #include <fstream>
23 #include <iostream>
24 #include <parameter.h>
25 #include <parameters.h>
26 #include <sstream>
27 #include <sys/file.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <unistd.h>
31 #include <sys/stat.h>
32 
33 #include "application_info.h"
34 #include "bundle_mgr_proxy.h"
35 #include "file_ex.h"
36 #include "hisysevent.h"
37 #include "iservice_registry.h"
38 #include "logging.h"
39 #include "system_ability_definition.h"
40 #include "os_account_info.h"
41 #include "os_account_manager.h"
42 
43 using namespace OHOS;
44 using namespace OHOS::AppExecFwk;
45 namespace COMMON {
46 namespace {
47 const std::map<std::string, clockid_t> clockIdMap = {
48     {"realtime",            CLOCK_REALTIME},
49     {"mono",                CLOCK_MONOTONIC},
50     {"process_cputime_id",  CLOCK_PROCESS_CPUTIME_ID},
51     {"thread_cputime_id",   CLOCK_THREAD_CPUTIME_ID},
52     {"mono_raw",            CLOCK_MONOTONIC_RAW},
53     {"realtime_coarse",     CLOCK_REALTIME_COARSE},
54     {"mono_coarse",         CLOCK_MONOTONIC_COARSE},
55     {"boot",                CLOCK_BOOTTIME},
56     {"realtime_alarm",      CLOCK_REALTIME_ALARM},
57     {"boot_alarm",          CLOCK_BOOTTIME_ALARM},
58     {"sgi_cycle",           CLOCK_SGI_CYCLE},
59     {"tai",                 CLOCK_TAI},
60 };
61 constexpr int EXECVP_ERRNO = 2;
62 const int SHELL_UID = 2000;
63 const std::string DEFAULT_PATH = "/data/local/tmp/";
64 constexpr int READ = 0;
65 constexpr int WRITE = 1;
66 const int FILE_PATH_SIZE = 512;
67 const int BUFFER_SIZE = 1024;
68 const int INVALID_PID = -1;
69 constexpr int32_t EC_INVALID_VALUE = -2;
70 const std::string KEY_HIVIEW_USER_TYPE = "const.logsystem.versiontype";
71 const uint32_t MAX_CMD_ARGV = 50;
72 const uint32_t MIN_CMD_ARGV = 2;
73 const std::set<std::string> CMD_WHITE_LIST = {
74     "/system/bin/hiperf",    "/system/bin/hitrace",     "/system/bin/hisysevent",         "/system/bin/hidumper",
75     "/system/bin/SP_daemon", "/system/bin/hiprofilerd", "/system/bin/hiprofiler_plugins", "/system/bin/native_daemon",
76     "/system/bin/hilog"};
77 }  // namespace
78 
IsProcessRunning(int & lockFileFd)79 bool IsProcessRunning(int& lockFileFd)
80 {
81     setgid(SHELL_UID);
82     char buffer[PATH_MAX + 1] = {0};
83     readlink("/proc/self/exe", buffer, PATH_MAX);
84     std::string processName = buffer;
85     int pos = static_cast<int>(processName.find_last_of('/'));
86     if (pos != 0) {
87         processName = processName.substr(pos + 1, processName.size());
88     }
89 
90     std::string fileName = DEFAULT_PATH + processName + ".pid";
91     umask(S_IWOTH);
92     int fd = open(fileName.c_str(), O_WRONLY | O_CREAT, static_cast<mode_t>(0664)); // 0664: rw-rw-r--
93     if (fd < 0) {
94         const int bufSize = 256;
95         char buf[bufSize] = {0};
96         strerror_r(errno, buf, bufSize);
97         PROFILER_LOG_ERROR(LOG_CORE, "%s:failed to open(%s), errno(%d:%s)", __func__, fileName.c_str(), errno, buf);
98         return false;
99     }
100     int flags = fcntl(fd, F_GETFD);
101     if (flags == -1) {
102         close(fd);
103         PROFILER_LOG_ERROR(LOG_CORE, "%s: get fd flags failed!", __func__);
104         return false;
105     }
106     flags |= FD_CLOEXEC;
107     if (fcntl(fd, F_SETFD, flags) == -1) {
108         close(fd);
109         PROFILER_LOG_ERROR(LOG_CORE, "%s: set fd_cloexec failed!", __func__);
110         return false;
111     }
112     if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
113         // 进程正在运行,加锁失败
114         close(fd);
115         printf("%s is running, please don't start it again.\n", processName.c_str());
116         PROFILER_LOG_ERROR(LOG_CORE, "%s is running, please don't start it again.", processName.c_str());
117         return true;
118     }
119     std::string pidStr = std::to_string(getpid());
120     auto nbytes = write(fd, pidStr.data(), pidStr.size());
121     lockFileFd = fd;
122     CHECK_TRUE(static_cast<size_t>(nbytes) == pidStr.size(), false, "write pid FAILED!");
123     return false;
124 }
125 
IsProcessExist(const std::string & processName,int & pid)126 bool IsProcessExist(const std::string& processName, int& pid)
127 {
128     DIR* dir = opendir("/proc");
129     CHECK_NOTNULL(dir, false, "open /proc dir failed");
130     struct dirent* ptr;
131     int pidValue = INVALID_PID;
132     while ((ptr = readdir(dir)) != nullptr) {
133         if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
134             continue;
135         }
136         if ((!isdigit(*ptr->d_name)) || ptr->d_type != DT_DIR) {
137             continue;
138         }
139         if (!IsNumeric(std::string(ptr->d_name))) {
140             continue;
141         }
142         char filePath[FILE_PATH_SIZE] = {0};
143         int len = snprintf_s(filePath, FILE_PATH_SIZE, FILE_PATH_SIZE - 1, "/proc/%s/cmdline", ptr->d_name);
144         if (len < 0) {
145             PROFILER_LOG_WARN(LOG_CORE, "maybe, the contents of cmdline had be cut off");
146             continue;
147         }
148         FILE* fp = fopen(filePath, "r");
149         if (fp == nullptr) {
150             continue;
151         }
152         char buf[BUFFER_SIZE] = {0};
153         if (fgets(buf, sizeof(buf) - 1, fp) == nullptr) {
154             fclose(fp);
155             continue;
156         }
157         std::string str(buf);
158         size_t found = str.rfind("/");
159         std::string fullProcess;
160         if (found != std::string::npos) {
161             fullProcess = str.substr(found + 1);
162         } else {
163             fullProcess = str;
164         }
165         if (fullProcess == processName) {
166             pidValue = atoi(ptr->d_name);
167             fclose(fp);
168             break;
169         }
170         fclose(fp);
171     }
172     closedir(dir);
173     if (pidValue != INVALID_PID) {
174         pid = pidValue;
175     }
176     return pidValue != INVALID_PID;
177 }
178 
CloseStdio()179 static void CloseStdio()
180 {
181     close(STDIN_FILENO);
182     close(STDOUT_FILENO);
183     close(STDERR_FILENO);
184 }
185 
StartProcess(const std::string & processBin,std::vector<char * > & argv)186 int StartProcess(const std::string& processBin, std::vector<char*>& argv)
187 {
188     if (argv.size() > MAX_CMD_ARGV || argv.size() < 1) {
189         PROFILER_LOG_ERROR(LOG_CORE, "%s: param invalid", __func__);
190         return -1;
191     }
192     // check whitelist
193     if (!CheckWhiteList(processBin)) {
194         PROFILER_LOG_ERROR(LOG_CORE, "%s: command not in whitelist!", __func__);
195         return -1;
196     }
197     for (auto& item : argv) {
198         std::string itemStr(item);
199         if (!CheckCmdLineArgValid(itemStr)) {
200             PROFILER_LOG_ERROR(LOG_CORE, "%s: command arg invalid : %s", __func__, itemStr.c_str());
201             return -1;
202         }
203     }
204     int pid = fork();
205     if (pid == 0) {
206         CloseStdio();
207         argv.push_back(nullptr); // last item in argv must be NULL
208         int retval = execv(processBin.data(), argv.data());
209         if (retval == -1 && errno == EXECVP_ERRNO) {
210             printf("warning: %s does not exist!\n", processBin.c_str());
211             PROFILER_LOG_WARN(LOG_CORE, "warning: %s does not exist!", processBin.c_str());
212         }
213         _exit(EXIT_FAILURE);
214     }
215 
216     return pid;
217 }
218 
KillProcess(int pid)219 int KillProcess(int pid)
220 {
221     if (pid == -1) {
222         return -1;
223     }
224     int stat;
225     kill(pid, SIGTERM);
226     if (waitpid(pid, &stat, 0) == -1) {
227         if (errno != EINTR) {
228             stat = -1;
229         }
230     }
231     return stat;
232 }
233 
CheckSubscribeVersion(const std::string & version)234 bool CheckSubscribeVersion(const std::string& version)
235 {
236     char* end;
237     double number = std::strtod(version.c_str(), &end);
238     if (end == version.c_str() + version.size()) {
239         return number >= 1.0;
240     } else {
241         PROFILER_LOG_INFO(LOG_CORE, "current version doesn't support event push");
242         return false;
243     }
244 }
245 
PrintMallinfoLog(const std::string & mallInfoPrefix,const struct mallinfo2 & mi)246 void PrintMallinfoLog(const std::string& mallInfoPrefix, const struct mallinfo2& mi)
247 {
248 #ifdef HOOK_ENABLE
249     std::string mallinfoLog = mallInfoPrefix;
250     mallinfoLog += "arena = " + std::to_string(mi.arena) + ", ordblks = " + std::to_string(mi.ordblks);
251     mallinfoLog += ", smblks = " + std::to_string(mi.smblks) + ", hblks = " + std::to_string(mi.hblks);
252     mallinfoLog += ", hblkhd = " + std::to_string(mi.hblkhd) + ", usmblks = " + std::to_string(mi.usmblks);
253     mallinfoLog +=
254         ", fsmblks = " + std::to_string(mi.fsmblks) + ", uordblks = " + std::to_string(mi.uordblks);
255     mallinfoLog +=
256         ", fordblks = " + std::to_string(mi.fordblks) + ", keepcost = " + std::to_string(mi.keepcost);
257     PROFILER_LOG_INFO(LOG_CORE, "%s", mallinfoLog.c_str());
258 #endif  // HOOK_ENABLE
259 }
260 
GetDeveloperMode()261 bool GetDeveloperMode()
262 {
263     bool developerMode = OHOS::system::GetBoolParameter("const.security.developermode.state", true);
264     if (!developerMode) {
265         PROFILER_LOG_INFO(LOG_CORE, "It is not developer mode!");
266     }
267     return developerMode;
268 }
269 
CustomFdClose(int & fd)270 inline int CustomFdClose(int& fd)
271 {
272     int ret = close(fd);
273     if (ret == 0) {
274         fd = -1;
275     }
276     return ret;
277 }
278 
CustomFdFclose(FILE ** fp)279 inline int CustomFdFclose(FILE** fp)
280 {
281     int ret = fclose(*fp);
282     if (ret == 0) {
283         *fp = nullptr;
284     }
285     return ret;
286 }
287 
CustomPopen(const std::vector<std::string> & command,const char * type,int fds[],volatile pid_t & childPid,bool needUnblock)288 FILE* CustomPopen(const std::vector<std::string>& command, const char* type, int fds[],
289                   volatile pid_t& childPid, bool needUnblock)
290 {
291     PROFILER_LOG_DEBUG(LOG_CORE, "BEGN %s: ready!", __func__);
292     if (command.size() < MIN_CMD_ARGV || command.size() > MAX_CMD_ARGV || type == nullptr || strlen(type) != 1) {
293         PROFILER_LOG_ERROR(LOG_CORE, "%s: param invalid", __func__);
294         return nullptr;
295     }
296 
297     // only allow "r" or "w"
298     if ((type[0] != 'r' && type[0] != 'w')) {
299         errno = EINVAL;
300         return  nullptr;
301     }
302     // check whitelist
303     if (!CheckWhiteList(command[0])) {
304         PROFILER_LOG_ERROR(LOG_CORE, "%s: command not in whitelist!", __func__);
305         return nullptr;
306     }
307     // check cmd arg valid
308     for (auto& item : command) {
309         if (!CheckCmdLineArgValid(item)) {
310             PROFILER_LOG_ERROR(LOG_CORE, "%s: command arg invalid : %s", __func__, item.c_str());
311             return nullptr;
312         }
313     }
314     CHECK_TRUE(pipe(fds) == 0, nullptr, "Pipe open failed!");
315     pid_t pid = fork();
316     if (pid == -1) {
317         perror("fork");
318         exit(1);
319     }
320 
321     if (pid == 0) {
322         // execve : the last argv must be nullptr.
323         std::vector<char*> argv(command.size() + 1, nullptr);
324         for (size_t i = 0, cmdSize = command.size(); i < cmdSize; i++) {
325             argv[i] = const_cast<char*>(command[i].data());
326         }
327 
328         if (strncmp(type, "r", strlen(type)) == 0) {
329             CHECK_TRUE(CustomFdClose(fds[READ]) == 0, nullptr, "CustomFdClose failed!");
330             dup2(fds[WRITE], STDOUT_FILENO); // Redirect stdout to pipe
331             CHECK_TRUE(CustomFdClose(fds[WRITE]) == 0, nullptr, "CustomFdClose failed!");
332         } else {
333             CHECK_TRUE(CustomFdClose(fds[WRITE]) == 0, nullptr, "CustomFdClose failed!");
334             dup2(fds[READ], STDIN_FILENO); // Redirect stdin to pipe
335             CHECK_TRUE(CustomFdClose(fds[READ]) == 0, nullptr, "CustomFdClose failed!");
336         }
337 
338         setpgid(pid, pid);
339         // exe path = argv[0]; exe name = argv[1]
340         if (execv(argv[0], &argv[1]) == -1) {
341             PROFILER_LOG_ERROR(LOG_CORE, "execv failed {%s:%s}", __func__, strerror(errno));
342             exit(EXIT_FAILURE);
343         }
344     }
345 
346     if (!needUnblock) {
347         if (strncmp(type, "r", strlen(type)) == 0) {
348             // Close the WRITE end of the pipe since parent's fd is read-only
349             CHECK_TRUE(CustomFdClose(fds[WRITE]) == 0, nullptr, "%s %d CustomFdClose failed! errno(%s)\n",
350                 __func__, __LINE__, strerror(errno));
351         } else {
352             // Close the READ end of the pipe since parent's fd is write-only
353             CHECK_TRUE(CustomFdClose(fds[READ]) == 0, nullptr, "%s %d CustomFdClose failed! errno(%s)\n",
354                 __func__, __LINE__, strerror(errno));
355         }
356     }
357 
358     // Make sure the parent pipe reads and writes exist;CustomPUnblock will use.
359     childPid = pid;
360     if (strncmp(type, "r", strlen(type)) == 0) {
361         PROFILER_LOG_DEBUG(LOG_CORE, "END %s fds[READ]: success!", __func__);
362         return fdopen(fds[READ], "r");
363     }
364 
365     PROFILER_LOG_DEBUG(LOG_CORE, "END %s fds[WRITE]: success!", __func__);
366     return fdopen(fds[WRITE], "w");
367 }
368 
IsNumeric(const std::string & str)369 bool IsNumeric(const std::string& str)
370 {
371     std::istringstream iss(str);
372     int number;
373     char trailingCharacter;
374     if (!(iss >> number)) {
375         return false;
376     }
377     if (iss >> trailingCharacter) {
378         return false;
379     }
380     return true;
381 }
382 
CustomPclose(FILE * fp,int fds[],volatile pid_t & childPid,bool needUnblock)383 int CustomPclose(FILE* fp, int fds[], volatile pid_t& childPid, bool needUnblock)
384 {
385     PROFILER_LOG_DEBUG(LOG_CORE, "BEGN %s: ready!", __func__);
386     CHECK_NOTNULL(fp, -1, "NOTE %s: fp is null", __func__);
387 
388     int stat = 0;
389 
390     if (needUnblock) {
391         PROFILER_LOG_DEBUG(LOG_CORE, "NOTE Kill Endless Loop Child %d.", childPid);
392         kill(childPid, SIGKILL);
393     }
394 
395     while (waitpid(childPid, &stat, 0) == -1) {
396         PROFILER_LOG_ERROR(LOG_CORE, "%s: %s.", __func__, strerror(errno));
397         if (errno == EINTR) {
398             continue;
399         }
400         break;
401     }
402 
403     if (needUnblock) {
404         if (fileno(fp) == fds[READ]) {
405             fds[READ] = -1;
406             if (CustomFdClose(fds[WRITE]) != 0) {
407                 PROFILER_LOG_ERROR(LOG_CORE, "CustomFdClose failed!");
408                 CHECK_TRUE(CustomFdFclose(&fp) == 0, -1, "CustomFdFclose failed!");
409                 return -1;
410             }
411         } else if (fileno(fp) == fds[WRITE]) {
412             fds[WRITE] = -1;
413             if (CustomFdClose(fds[READ]) != 0) {
414                 PROFILER_LOG_ERROR(LOG_CORE, "CustomFdClose failed!");
415                 CHECK_TRUE(CustomFdFclose(&fp) == 0, -1, "CustomFdFclose failed!");
416                 return -1;
417             }
418         } else {
419             PROFILER_LOG_INFO(LOG_CORE, "%s: Can't find fp in fds[READ/WRITE].", __func__);
420         }
421     }
422 
423     CHECK_TRUE(CustomFdFclose(&fp) == 0, -1, "CustomFdFclose failed!");
424 
425     PROFILER_LOG_DEBUG(LOG_CORE, "END %s: success!", __func__);
426     return stat;
427 }
428 
429 // IF pipe fds is block, before release other threads, you need call CustomPUnblock
CustomPUnblock(int fds[])430 int CustomPUnblock(int fds[])
431 {
432     PROFILER_LOG_DEBUG(LOG_CORE, "BEGN %s: ready!", __func__);
433 
434     CHECK_TRUE(fds[READ] != -1 && fds[WRITE] != -1, -1, "END fds[READ/WRITE]=-1");
435 
436     int stat = fcntl(fds[READ], F_GETFL);
437     CHECK_TRUE(stat != -1, -1, "END fcntl(F_GETFL) failed!");
438 
439     if (!(stat & O_NONBLOCK)) {
440         PROFILER_LOG_DEBUG(LOG_CORE, "NOTE %s: ready!Unblock r_fd and close all", __func__);
441         const char* eof = "\n\0";
442         write(fds[WRITE], eof, strlen(eof) + 1);
443         fcntl(fds[READ], F_SETFL, O_NONBLOCK);
444     }
445     PROFILER_LOG_DEBUG(LOG_CORE, "END %s: success!", __func__);
446     return 0;
447 }
448 
GetServicePort()449 int GetServicePort()
450 {
451     const std::string portRangePath = "/proc/sys/net/ipv4/ip_local_port_range";
452     std::ifstream file(portRangePath.c_str());
453     CHECK_TRUE(file.is_open(), -1, "Open file failed! filePath:%s", portRangePath.c_str());
454 
455     std::string rangeStr;
456     copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(rangeStr));
457 
458     int minPort;
459     int maxPort;
460     std::istringstream istr(rangeStr);
461     istr >> minPort >> maxPort;
462     const int offset = 3168; // To be compatible with previously used port 50051;
463     int port = (minPort + maxPort) / 2 + offset;
464     PROFILER_LOG_DEBUG(LOG_CORE, "Service port is: %d", port);
465     return port;
466 }
467 
SplitString(const std::string & str,const std::string & sep,std::vector<std::string> & ret)468 void SplitString(const std::string& str, const std::string &sep, std::vector<std::string>& ret)
469 {
470     if (str.empty()) {
471         PROFILER_LOG_ERROR(LOG_CORE, "The string splited is empty!");
472         return;
473     }
474     std::string::size_type beginPos = str.find_first_not_of(sep);
475     std::string::size_type findPos = 0;
476     while (beginPos != std::string::npos) {
477         findPos = str.find(sep, beginPos);
478         std::string tmp;
479         if (findPos != std::string::npos) {
480             tmp = str.substr(beginPos, findPos - beginPos);
481             beginPos = findPos + sep.length();
482         } else {
483             tmp = str.substr(beginPos);
484             beginPos = findPos;
485         }
486         if (!tmp.empty()) {
487             ret.push_back(tmp);
488             tmp.clear();
489         }
490     }
491 }
492 
CheckApplicationPermission(int pid,const std::string & processName)493 bool CheckApplicationPermission(int pid, const std::string& processName)
494 {
495     std::string bundleName;
496     if (pid > 0) {
497         std::string filePath = "/proc/" + std::to_string(pid) + "/cmdline";
498         if (!LoadStringFromFile(filePath, bundleName)) {
499             PROFILER_LOG_ERROR(LOG_CORE, "Get process name by pid failed!");
500             return false;
501         }
502         bundleName.resize(strlen(bundleName.c_str()));
503     } else {
504         bundleName = processName;
505     }
506     auto pos = bundleName.find(":");
507     if (pos != std::string::npos) {
508         bundleName = bundleName.substr(0, pos);
509     }
510     CHECK_TRUE(!bundleName.empty(), false, "Pid or process name is illegal!");
511 
512     sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
513     CHECK_NOTNULL(sam, false, "GetSystemAbilityManager failed!");
514     sptr<IRemoteObject> remoteObject = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
515     CHECK_NOTNULL(remoteObject, false, "Get BundleMgr SA failed!");
516     sptr<BundleMgrProxy> proxy = iface_cast<BundleMgrProxy>(remoteObject);
517     AppExecFwk::ApplicationInfo appInfo;
518     bool ret = proxy->GetApplicationInfo(bundleName, AppExecFwk::GET_APPLICATION_INFO_WITH_DISABLE,
519                                          AppExecFwk::Constants::ANY_USERID, appInfo);
520     if (!ret) {
521         PROFILER_LOG_ERROR(LOG_CORE, "GetApplicationInfo failed!");
522         return false;
523     }
524     return appInfo.appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG;
525 }
CheckApplicationEncryped(int pid,const std::string & processName)526 bool CheckApplicationEncryped(int pid, const std::string& processName)
527 {
528     std::string bundleName;
529     if (pid > 0) {
530         std::string filePath = "/proc/" + std::to_string(pid) + "/cmdline";
531         if (!LoadStringFromFile(filePath, bundleName)) {
532             PROFILER_LOG_ERROR(LOG_CORE, "Get process name by pid failed!");
533             return false;
534         }
535         bundleName.resize(strlen(bundleName.c_str()));
536     } else {
537         bundleName = processName;
538     }
539     auto pos = bundleName.find(":");
540     if (pos != std::string::npos) {
541         bundleName = bundleName.substr(0, pos);
542     }
543     CHECK_TRUE(!bundleName.empty(), false, "Pid or process name is illegal!");
544     sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
545     CHECK_NOTNULL(sam, false, "GetSystemAbilityManager failed!");
546     sptr<IRemoteObject> remoteObject = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
547     CHECK_NOTNULL(remoteObject, false, "Get BundleMgr SA failed!");
548     sptr<BundleMgrProxy> proxy = iface_cast<BundleMgrProxy>(remoteObject);
549     AppExecFwk::ApplicationInfo appInfo;
550     bool ret = proxy->GetApplicationInfo(bundleName, AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO,
551                                          AppExecFwk::Constants::ANY_USERID, appInfo);
552     CHECK_TRUE(ret, false, "%s:%s GetApplicationInfo failed!", __func__, bundleName.c_str());
553     bool isEncrypted = (appInfo.applicationReservedFlag &
554                         static_cast<uint32_t>(AppExecFwk::ApplicationReservedFlag::ENCRYPTED_APPLICATION)) != 0;
555     PROFILER_LOG_INFO(LOG_CORE, "%s: check application encryped.%d : %s", __func__, isEncrypted, bundleName.c_str());
556     return isEncrypted;
557 }
558 
VerifyPath(const std::string & filePath,const std::vector<std::string> & validPaths)559 bool VerifyPath(const std::string& filePath, const std::vector<std::string>& validPaths)
560 {
561     if (validPaths.size() == 0) {
562         return true;
563     }
564 
565     for (const std::string& path : validPaths) {
566         if (filePath.rfind(path, 0) == 0) {
567             return true;
568         }
569     }
570     return false;
571 }
572 
RealPath(std::string & filePath)573 const char* RealPath(std::string &filePath)
574 {
575     if (filePath.size() > 0 && (filePath.back() == '/' || filePath.back() == '.')) {
576         return nullptr;
577     }
578     if (filePath.find('.') == std::string::npos) {
579         return filePath.c_str();
580     }
581     std::vector<std::string> paths;
582     SplitString(filePath, "/", paths);
583     std::vector<std::string> validPaths;
584     for (std::string& pathName: paths) {
585         if (pathName == "..") {
586             if (validPaths.size() == 0) {
587                 return nullptr;
588             } else {
589                 validPaths.pop_back();
590             }
591         } else {
592             validPaths.emplace_back(pathName);
593         }
594     }
595     filePath = "/";
596     for (const std::string &pathName : validPaths) {
597         filePath += pathName;
598         filePath += "/";
599     }
600     filePath.pop_back();
601     return filePath.c_str();
602 }
603 
ReadFile(const std::string & filePath,const std::vector<std::string> & validPaths,std::string & fileContent)604 bool ReadFile(const std::string &filePath, const std::vector<std::string>& validPaths, std::string& fileContent)
605 {
606     std::string pathName = filePath;
607     const char* realFilePath = RealPath(pathName);
608     CHECK_NOTNULL(realFilePath, false, "Fail to realPath: %s", filePath.c_str());
609 
610     std::string realFilePathStr(realFilePath);
611     CHECK_TRUE(VerifyPath(realFilePathStr, validPaths), false, "Fail to VerifyPath: %s", realFilePathStr.c_str());
612 
613     std::ifstream fileStream(realFilePathStr, std::ios::in);
614     CHECK_TRUE(fileStream.is_open(), false, "Fail to open file %s", realFilePathStr.c_str());
615 
616     std::istreambuf_iterator<char> firstIt = { fileStream };
617     std::string content(firstIt, {});
618     fileContent = content;
619     return true;
620 }
621 
IsUserMode()622 bool IsUserMode()
623 {
624     std::string debugMode = "0";
625     debugMode = OHOS::system::GetParameter("const.debuggable", debugMode);
626     if (debugMode != "0") {
627         PROFILER_LOG_INFO(LOG_CORE, "It is not user mode!");
628     }
629     return debugMode == "0";
630 }
631 
GetErrorMsg()632 std::string GetErrorMsg()
633 {
634     const int bufSize = 256;
635     char buffer[bufSize] = { 0 };
636     strerror_r(errno, buffer, bufSize);
637     std::string errorMsg(buffer);
638     return errorMsg;
639 }
640 
GetTimeStr()641 std::string GetTimeStr()
642 {
643     time_t now = time(nullptr);
644     struct tm tmTime;
645     localtime_r(&now, &tmTime);
646 
647     char buffer[32] = {0};
648     // 1900: count of years
649     (void)sprintf_s(buffer, sizeof(buffer), "%04d%02d%02d_%02d%02d%02d", tmTime.tm_year + 1900, tmTime.tm_mon + 1,
650         tmTime.tm_mday, tmTime.tm_hour, tmTime.tm_min, tmTime.tm_sec);
651     std::string timeStr(buffer);
652     return timeStr;
653 }
654 
655 // get clockid by str, return CLOCK_REALTIME as default
GetClockId(const std::string & clockIdStr)656 clockid_t GetClockId(const std::string& clockIdStr)
657 {
658     clockid_t clockId = CLOCK_REALTIME;
659     auto iter = clockIdMap.find(clockIdStr);
660     if (iter != clockIdMap.end()) {
661         clockId = iter->second;
662     }
663     return clockId;
664 }
665 
GetClockStr(const int32_t clockId)666 std::string GetClockStr(const int32_t clockId)
667 {
668     std::string ret = "realtime";
669     for (const auto& [str, id] : clockIdMap) {
670         if (id == clockId) {
671             ret = str;
672             break;
673         }
674     }
675     return ret;
676 }
677 
AdaptSandboxPath(std::string & filePath,int pid)678 void AdaptSandboxPath(std::string& filePath, int pid)
679 {
680     if (filePath.find("/data/storage") == 0 && access(filePath.c_str(), F_OK) != 0) {
681         filePath = "/proc/" + std::to_string(pid) + "/root" + filePath;
682     }
683 }
684 
GetCurrentUserId(int32_t & userId)685 bool GetCurrentUserId(int32_t& userId)
686 {
687     std::vector<int32_t> activeIds;
688     int32_t ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeIds);
689     if (ret != 0) {
690         PROFILER_LOG_ERROR(LOG_CORE, "QueryActiveOsAccountIds failed ret:%d", ret);
691         return false;
692     }
693 
694     if (activeIds.empty()) {
695         PROFILER_LOG_ERROR(LOG_CORE, "QueryActiveOsAccountIds activeIds empty");
696         return false;
697     }
698     userId = activeIds[0];
699     PROFILER_LOG_INFO(LOG_CORE, "QueryActiveOsAccountIds userId[0]:%d", userId);
700     return true;
701 }
702 
GetPackageUid(const std::string & name)703 int32_t GetPackageUid(const std::string& name)
704 {
705     int32_t userId = 0;
706     if (!GetCurrentUserId(userId)) {
707         PROFILER_LOG_ERROR(LOG_CORE, "Failed to get current user id");
708         return EC_INVALID_VALUE;
709     }
710     auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
711     if (manager == nullptr) {
712         PROFILER_LOG_ERROR(LOG_CORE, "systemAbilityManager is nullptr");
713         return EC_INVALID_VALUE;
714     }
715     sptr<IRemoteObject> remoteObject = manager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
716     if (remoteObject == nullptr) {
717         PROFILER_LOG_ERROR(LOG_CORE, "failed to get service id");
718         return EC_INVALID_VALUE;
719     }
720     sptr<AppExecFwk::IBundleMgr> mgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
721     if (mgr == nullptr) {
722         PROFILER_LOG_ERROR(LOG_CORE, "mgr is nullptr");
723         return EC_INVALID_VALUE;
724     }
725     int32_t uid = mgr->GetUidByBundleName(name, userId);
726     PROFILER_LOG_INFO(LOG_CORE, "pkgname is: %s, uid is : %d", name.c_str(), uid);
727     return uid;
728 }
729 
IsBetaVersion()730 bool IsBetaVersion()
731 {
732     int ret = static_cast<int>(FindParameter(KEY_HIVIEW_USER_TYPE.c_str()));
733     if (ret == -1) {
734         PROFILER_LOG_INFO(LOG_CORE, "user type is not exist");
735         return true;
736     }
737     std::string userType = OHOS::system::GetParameter(KEY_HIVIEW_USER_TYPE, "");
738     PROFILER_LOG_INFO(LOG_CORE, "user type is:%s", userType.c_str());
739     return userType == "beta";
740 }
741 
CheckNotExistsFilePath(const std::string & filePath)742 std::pair<bool, std::string> CheckNotExistsFilePath(const std::string& filePath)
743 {
744     size_t pos = filePath.rfind('/');
745     std::string pathDir = "";
746     if (pos != std::string::npos) {
747         pathDir = filePath.substr(0, pos);
748     } else {
749         pathDir = ".";
750     }
751     std::unique_ptr<char[]> pathDirRealPath = std::make_unique<char[]>(PATH_MAX);
752     if ((pathDir.length() >= PATH_MAX - 1) || (realpath(pathDir.c_str(), pathDirRealPath.get()) == nullptr)) {
753         PROFILER_LOG_ERROR(LOG_CORE, "%s:path is invalid: %s, errno=%d", __func__, pathDir.c_str(), errno);
754         return {false, ""};
755     }
756     if (access(pathDir.c_str(), F_OK) != 0) {
757         PROFILER_LOG_ERROR(LOG_CORE, "%s:Fail to access path: %s", __func__, pathDir.c_str());
758         return {false, ""};
759     }
760     return {true, std::string(pathDirRealPath.get()) + "/" + filePath.substr(pos + 1)};
761 }
762 
CheckWhiteList(const std::string & cmdPath)763 bool CheckWhiteList(const std::string& cmdPath)
764 {
765     if (cmdPath.empty()) {
766         PROFILER_LOG_ERROR(LOG_CORE, "cmd is empty {%s}", __func__);
767         return false;
768     }
769 
770     if (CMD_WHITE_LIST.find(cmdPath) == CMD_WHITE_LIST.end() ||
771         cmdPath.find_first_of("|;&${}<>'\\!\n~?*%[]^") != std::string::npos) {
772         PROFILER_LOG_ERROR(LOG_CORE, "cmd %s:is illegal {%s}", cmdPath.c_str(), __func__);
773         return false;
774     }
775     return true;
776 }
777 
CheckCmdLineArgValid(const std::string & cmdLine)778 bool CheckCmdLineArgValid(const std::string& cmdLine)
779 {
780     if (cmdLine.empty()) {
781         PROFILER_LOG_ERROR(LOG_CORE, "cmdLine is empty {%s}", __func__);
782         return false;
783     }
784 
785     if (cmdLine.find_first_of("|;&${}<>'\\!\n~?*%[]^") != std::string::npos) {
786         PROFILER_LOG_ERROR(LOG_CORE, "cmdLine %s is illegal {%s}", cmdLine.c_str(), __func__);
787         return false;
788     }
789     return true;
790 }
791 
PluginWriteToHisysevent(const std::string & pluginName,const std::string & caller,const std::string & args,int errorCode,const std::string & errorMessage)792 int PluginWriteToHisysevent(const std::string& pluginName, const std::string& caller, const std::string& args,
793                             int errorCode, const std::string& errorMessage)
794 {
795     return HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::PROFILER, "HIPROFILER_USAGE",
796         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
797         "PLUGIN_NAME", pluginName,
798         "CALLER", caller,
799         "ARGS", args,
800         "ERROR_CODE", errorCode,
801         "ERROR_MESSAGE", errorMessage);
802 }
803 
GetProcessNameByPid(int32_t pid)804 std::string GetProcessNameByPid(int32_t pid)
805 {
806     std::string path = "/proc/" + std::to_string(pid) + "/cmdline";
807     std::ifstream cmdlineFile(path);
808     if (!cmdlineFile) {
809         return "";
810     }
811     if (cmdlineFile.fail()) {
812         return "";
813     }
814 
815     std::string processName;
816     std::getline(cmdlineFile, processName, '\0');
817     if (processName.empty()) {
818         return "";
819     }
820     static constexpr size_t headSize = 2;
821     if (processName.substr(0, headSize) == "./") {
822         processName = processName.substr(headSize);
823     }
824     size_t found = processName.rfind("/");
825     std::string procName;
826     if (found != std::string::npos) {
827         procName = processName.substr(found + 1);
828     } else {
829         procName = processName;
830     }
831     return procName;
832 }
833 } // namespace COMMON
834