• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include <csignal>
16 #include <sys/prctl.h>
17 #include <vector>
18 
19 #include "errors.h"
20 #include "local_ability_manager.h"
21 #include "parameter.h"
22 #include "safwk_log.h"
23 #include "securec.h"
24 #include "string_ex.h"
25 #include "system_ability_definition.h"
26 
27 using namespace OHOS;
28 using std::string;
29 
30 namespace {
31 const string TAG = "SaMain";
32 
33 using ProcessNameSetFunc = std::function<void(const string&)>;
34 
35 constexpr auto DEFAULT_XML = "/system/usr/default.xml";
36 // The pid name can be up to 16 bytes long, including the terminating null byte.
37 // So need to set the max length of pid name to 15 bytes.
38 constexpr size_t MAX_LEN_PID_NAME = 15;
39 
40 constexpr int PROFILE_INDEX = 1;
41 constexpr int SAID_INDEX = 2;
42 constexpr int DEFAULT_SAID = -1;
43 constexpr int DEFAULT_LOAD = 1;
44 constexpr int ONDEMAND_LOAD = 2;
45 }
46 
StartMemoryHook(const string & processName)47 static void StartMemoryHook(const string& processName)
48 {
49     const int paramBufLen = 128;
50     const char defaultValue[paramBufLen] = { 0 };
51     const char targetPrefix[] = "startup:";
52     const int targetPrefixLen = 8;
53     char paramValue[paramBufLen] = { 0 };
54     int retParam = GetParameter("libc.hook_mode", defaultValue, paramValue, sizeof(paramValue));
55     if (retParam <= 0 || strncmp(paramValue, targetPrefix, targetPrefixLen) != 0) {
56         return;
57     }
58 
59     if (processName.find(paramValue + targetPrefixLen) == 0) {
60         const int hookSignal = 36;
61         HILOGI(TAG, "raise hook signal %{public}d to %{public}s", hookSignal, processName.c_str());
62         raise(hookSignal);
63     }
64 }
65 
SetProcName(const string & filePath,const ProcessNameSetFunc & setProcessName)66 static void SetProcName(const string& filePath, const ProcessNameSetFunc& setProcessName)
67 {
68     std::vector<string> strVector;
69     SplitStr(filePath, "/", strVector);
70     auto vectorSize = strVector.size();
71     if (vectorSize > 0) {
72         auto& fileName = strVector[vectorSize - 1];
73         auto dotPos = fileName.find(".");
74         if (dotPos == string::npos) {
75             return;
76         }
77         if (dotPos > MAX_LEN_PID_NAME) {
78             dotPos = MAX_LEN_PID_NAME;
79         }
80         string profileName = fileName.substr(0, dotPos);
81         int32_t ret = prctl(PR_SET_NAME, profileName.c_str());
82         if (ret != 0) {
83             HILOGI(TAG, "call the system API prctl failed!");
84         }
85         setProcessName(profileName);
86         StartMemoryHook(profileName);
87     }
88 }
89 
90 // check argv size with SAID_INDEX before using the function
ParseSaId(char * argv[])91 static int32_t ParseSaId(char *argv[])
92 {
93     string saIdStr(argv[SAID_INDEX]);
94     int32_t saId = DEFAULT_SAID;
95     if (!StrToInt(saIdStr, saId)) {
96         return DEFAULT_SAID;
97     }
98     return saId;
99 }
100 
CheckSaId(int32_t saId)101 static bool CheckSaId(int32_t saId)
102 {
103     return (saId >= FIRST_SYS_ABILITY_ID) && (saId <= LAST_SYS_ABILITY_ID);
104 }
105 
main(int argc,char * argv[])106 int main(int argc, char *argv[])
107 {
108     HILOGI(TAG, "[PerformanceTest] SAFWK main entry process starting!");
109     auto setProcessName = [argc, argv](const string& name) -> void {
110         uintptr_t start = reinterpret_cast<uintptr_t>(argv[0]);
111         uintptr_t end = reinterpret_cast<uintptr_t>(strchr(argv[argc - 1], 0));
112         uintptr_t argvSize = end - start;
113 
114         if (memset_s(argv[0], argvSize, 0, argvSize) != EOK) {
115             HILOGW(TAG, "failed to clear argv:%s", strerror(errno));
116             return;
117         }
118         if (strcpy_s(argv[0], argvSize, name.c_str()) != EOK) {
119             HILOGW(TAG, "failed to set process name:%s", strerror(errno));
120             return;
121         }
122         HILOGI(TAG, "Set process name to %{public}s", argv[0]);
123     };
124     // Load ondemand system abilities related shared libraries from specific xml-format profile
125     // when this process starts.
126     int32_t saId = DEFAULT_SAID;
127     if (argc > ONDEMAND_LOAD) {
128         saId = ParseSaId(argv);
129         if (!CheckSaId(saId)) {
130             HILOGE(TAG, "saId is invalid!");
131             return 0;
132         }
133     }
134     // Load default system abilities related shared libraries from specific xml-format profile,
135     // when this process starts.
136     string profilePath(DEFAULT_XML);
137     if (argc > DEFAULT_LOAD) {
138         string filePath(argv[PROFILE_INDEX]);
139         if (filePath.empty() || filePath.find(".xml") == string::npos) {
140             HILOGE(TAG, "profile file path is invalid!");
141             return 0;
142         }
143         SetProcName(filePath, setProcessName);
144         profilePath = std::move(filePath);
145     }
146     LocalAbilityManager::GetInstance().DoStartSAProcess(profilePath, saId);
147     return 0;
148 }
149