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