• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "hiview_service_ability_stub.h"
17 
18 #include <unordered_map>
19 #include <vector>
20 
21 #include "accesstoken_kit.h"
22 #include "ash_memory_utils.h"
23 #include "client/trace_collector.h"
24 #include "errors.h"
25 #include "hiview_err_code.h"
26 #include "ipc_skeleton.h"
27 #include "logger.h"
28 
29 namespace OHOS {
30 namespace HiviewDFX {
31 namespace {
32 DEFINE_LOG_TAG("HiViewSA-HiViewServiceAbilityStub");
33 const std::string ASH_MEM_NAME = "HiviewLogLibrary SharedMemory";
34 constexpr uint32_t ASH_MEM_SIZE = 107 * 5000; // 535k
35 
36 const std::unordered_map<uint32_t, std::string> ALL_PERMISSION_MAP = {
37     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_LIST),
38         "ohos.permission.READ_HIVIEW_SYSTEM"},
39     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_COPY),
40         "ohos.permission.READ_HIVIEW_SYSTEM"},
41     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_MOVE),
42         "ohos.permission.WRITE_HIVIEW_SYSTEM"},
43     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_REMOVE),
44         "ohos.permission.WRITE_HIVIEW_SYSTEM"},
45     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_OPEN_SNAPSHOT_TRACE),
46         "ohos.permission.WRITE_HIVIEW_SYSTEM"},
47     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_DUMP_SNAPSHOT_TRACE),
48         "ohos.permission.READ_HIVIEW_SYSTEM"},
49     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_OPEN_RECORDING_TRACE),
50         "ohos.permission.WRITE_HIVIEW_SYSTEM"},
51     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECORDING_TRACE_ON),
52         "ohos.permission.READ_HIVIEW_SYSTEM"},
53     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECORDING_TRACE_OFF),
54         "ohos.permission.READ_HIVIEW_SYSTEM"},
55     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_CLOSE_TRACE),
56         "ohos.permission.WRITE_HIVIEW_SYSTEM"},
57     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECOVER_TRACE),
58         "ohos.permission.WRITE_HIVIEW_SYSTEM"}
59 };
60 
61 const std::unordered_map<uint32_t, std::string> TRACE_PERMISSION_MAP = {
62     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_OPEN_SNAPSHOT_TRACE),
63         "ohos.permission.DUMP"},
64     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_DUMP_SNAPSHOT_TRACE),
65         "ohos.permission.DUMP"},
66     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_OPEN_RECORDING_TRACE),
67         "ohos.permission.DUMP"},
68     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECORDING_TRACE_ON),
69         "ohos.permission.DUMP"},
70     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECORDING_TRACE_OFF),
71         "ohos.permission.DUMP"},
72     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_CLOSE_TRACE),
73         "ohos.permission.DUMP"},
74     {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECOVER_TRACE),
75         "ohos.permission.DUMP"}
76 };
77 
HasAccessPermission(uint32_t code,const std::unordered_map<uint32_t,std::string> & permissions)78 bool HasAccessPermission(uint32_t code, const std::unordered_map<uint32_t, std::string>& permissions)
79 {
80     using namespace Security::AccessToken;
81     auto iter = permissions.find(code);
82     if (iter == permissions.end()) {
83         return false;
84     }
85     AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
86     int verifyResult = AccessTokenKit::VerifyAccessToken(callerToken, iter->second);
87     if (verifyResult == PERMISSION_GRANTED) {
88         return true;
89     }
90     HIVIEW_LOGW("%{public}s not granted, code: %{public}u", iter->second.c_str(), code);
91     return false;
92 }
93 
WriteTracePracelableToMessage(MessageParcel & dest,Parcelable & data)94 int32_t WriteTracePracelableToMessage(MessageParcel& dest, Parcelable& data)
95 {
96     if (!dest.WriteParcelable(&data)) {
97         HIVIEW_LOGW("failed to write TraceErrorCodeWrapper to parcel");
98         return TraceErrCode::ERR_WRITE_MSG_PARCEL;
99     }
100     return TraceErrCode::ERR_OK;
101 }
102 }
103 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)104 int32_t HiviewServiceAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
105     MessageOption &option)
106 {
107     HIVIEW_LOGI("cmd = %{public}d, flags= %{public}d", code, option.GetFlags());
108     std::u16string descripter = HiviewServiceAbilityStub::GetDescriptor();
109     std::u16string remoteDescripter = data.ReadInterfaceToken();
110     if (descripter != remoteDescripter) {
111         return -ERR_INVALID_VALUE;
112     }
113     if (!IsPermissionGranted(code)) {
114         return HiviewNapiErrCode::ERR_PERMISSION_CHECK;
115     }
116     auto requestHandler = GetRequestHandler(code);
117     if (requestHandler == nullptr) {
118         return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
119     }
120     return requestHandler(data, reply, option);
121 }
122 
IsPermissionGranted(uint32_t code)123 bool HiviewServiceAbilityStub::IsPermissionGranted(uint32_t code)
124 {
125     return HasAccessPermission(code, ALL_PERMISSION_MAP) || HasAccessPermission(code, TRACE_PERMISSION_MAP);
126 }
127 
GetRequestHandlers()128 std::unordered_map<uint32_t, RequestHandler> HiviewServiceAbilityStub::GetRequestHandlers()
129 {
130     static std::unordered_map<uint32_t, RequestHandler> requestHandlers = {
131         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_LIST),
132             std::bind(&HiviewServiceAbilityStub::HandleListRequest, this,
133                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)},
134         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_COPY),
135             std::bind(&HiviewServiceAbilityStub::HandleCopyRequest, this,
136                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)},
137         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_MOVE),
138             std::bind(&HiviewServiceAbilityStub::HandleMoveRequest, this,
139                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)},
140         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_REMOVE),
141             std::bind(&HiviewServiceAbilityStub::HandleRemoveRequest, this,
142                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)}
143     };
144     return requestHandlers;
145 }
146 
GetTraceRequestHandlers()147 std::unordered_map<uint32_t, RequestHandler> HiviewServiceAbilityStub::GetTraceRequestHandlers()
148 {
149     static std::unordered_map<uint32_t, RequestHandler> requestHandlers = {
150         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_OPEN_SNAPSHOT_TRACE),
151             std::bind(&HiviewServiceAbilityStub::HandleOpenSnapshotTraceRequest, this,
152                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)},
153         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_DUMP_SNAPSHOT_TRACE),
154             std::bind(&HiviewServiceAbilityStub::HandleDumpSnapshotTraceRequest, this,
155                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)},
156         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_OPEN_RECORDING_TRACE),
157             std::bind(&HiviewServiceAbilityStub::HandleOpenRecordingTraceRequest, this,
158                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)},
159         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECORDING_TRACE_ON),
160             std::bind(&HiviewServiceAbilityStub::HandleRecordingTraceOnRequest, this,
161                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)},
162         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECORDING_TRACE_OFF),
163             std::bind(&HiviewServiceAbilityStub::HandleRecordingTraceOffRequest, this,
164                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)},
165         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_CLOSE_TRACE),
166             std::bind(&HiviewServiceAbilityStub::HandleCloseTraceRequest, this,
167                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)},
168         {static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECOVER_TRACE),
169             std::bind(&HiviewServiceAbilityStub::HandleRecoverTraceRequest, this,
170                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)}
171     };
172     return requestHandlers;
173 }
174 
GetRequestHandler(uint32_t code)175 RequestHandler HiviewServiceAbilityStub::GetRequestHandler(uint32_t code)
176 {
177     std::vector<std::unordered_map<uint32_t, RequestHandler>> allHandlerMaps = {
178         GetRequestHandlers(),
179         GetTraceRequestHandlers()
180     };
181     for (auto handlerMap : allHandlerMaps) {
182         auto iter = handlerMap.find(code);
183         if (iter == handlerMap.end()) {
184             continue;
185         }
186         return iter->second;
187     }
188     HIVIEW_LOGE("function for handling request isn't found");
189     return nullptr;
190 }
191 
HandleListRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)192 int32_t HiviewServiceAbilityStub::HandleListRequest(MessageParcel& data, MessageParcel& reply, MessageOption& option)
193 {
194     std::string logType;
195     if (!data.ReadString(logType)) {
196         HIVIEW_LOGE("cannot get log type");
197         return HiviewNapiErrCode::ERR_DEFAULT;
198     }
199     std::vector<HiviewFileInfo> fileInfos;
200     int32_t ret = List(logType, fileInfos);
201     if (ret != ERR_OK) {
202         return ret;
203     }
204     HIVIEW_LOGW("file list num:%{public}d", fileInfos.size());
205     sptr<Ashmem> ashmem = AshMemoryUtils::GetAshmem(ASH_MEM_NAME, ASH_MEM_SIZE);
206     if (ashmem == nullptr) {
207         HIVIEW_LOGE("ge ashmem failed.");
208         return HiviewNapiErrCode::ERR_DEFAULT;
209     }
210     std::vector<uint32_t> allSize;
211     if (!AshMemoryUtils::WriteBulkData<HiviewFileInfo>(fileInfos, ashmem, ASH_MEM_SIZE, allSize)) {
212         HIVIEW_LOGE("WriteBulkData failed.");
213         return HiviewNapiErrCode::ERR_DEFAULT;
214     }
215     if (!reply.WriteUInt32Vector(allSize)) {
216         HIVIEW_LOGE("write size failed.");
217         return HiviewNapiErrCode::ERR_DEFAULT;
218     }
219     if (!reply.WriteAshmem(ashmem)) {
220         HIVIEW_LOGE("write ashmem failed.");
221         return HiviewNapiErrCode::ERR_DEFAULT;
222     }
223     return ERR_OK;
224 }
225 
HandleCopyRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)226 int32_t HiviewServiceAbilityStub::HandleCopyRequest(MessageParcel& data, MessageParcel& reply, MessageOption& option)
227 {
228     return HandleCopyOrMoveRequest(data, reply, option, false);
229 }
230 
HandleMoveRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)231 int32_t HiviewServiceAbilityStub::HandleMoveRequest(MessageParcel& data, MessageParcel& reply, MessageOption& option)
232 {
233     return HandleCopyOrMoveRequest(data, reply, option, true);
234 }
235 
HandleCopyOrMoveRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option,bool isMove)236 int32_t HiviewServiceAbilityStub::HandleCopyOrMoveRequest(
237     MessageParcel& data, MessageParcel& reply, MessageOption& option, bool isMove)
238 {
239     std::string logType;
240     if (!data.ReadString(logType)) {
241         HIVIEW_LOGW("cannot get logtype");
242         return HiviewNapiErrCode::ERR_DEFAULT;
243     }
244     std::string logName;
245     if (!data.ReadString(logName)) {
246         HIVIEW_LOGW("cannot get log type");
247         return HiviewNapiErrCode::ERR_DEFAULT;
248     }
249     std::string dest;
250     if (!data.ReadString(dest)) {
251         HIVIEW_LOGW("cannot get dest dir");
252         return HiviewNapiErrCode::ERR_DEFAULT;
253     }
254     if (dest.find("..") != std::string::npos) {
255         HIVIEW_LOGW("invalid dest: %{public}s", dest.c_str());
256         return HiviewNapiErrCode::ERR_DEFAULT;
257     }
258     int32_t ret = isMove ? Move(logType, logName, dest) : Copy(logType, logName, dest);
259     if (!reply.WriteInt32(ret)) {
260         return HiviewNapiErrCode::ERR_DEFAULT;
261     }
262     return ERR_OK;
263 }
264 
HandleRemoveRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)265 int32_t HiviewServiceAbilityStub::HandleRemoveRequest(MessageParcel& data, MessageParcel& reply, MessageOption& option)
266 {
267     std::string logType;
268     if (!data.ReadString(logType)) {
269         HIVIEW_LOGW("cannot get log type");
270         return HiviewNapiErrCode::ERR_DEFAULT;
271     }
272     std::string logName;
273     if (!data.ReadString(logName)) {
274         HIVIEW_LOGW("cannot get log name");
275         return HiviewNapiErrCode::ERR_DEFAULT;
276     }
277     int32_t ret = Remove(logType, logName);
278     if (!reply.WriteInt32(ret)) {
279         return HiviewNapiErrCode::ERR_DEFAULT;
280     }
281     return ERR_OK;
282 }
283 
HandleOpenSnapshotTraceRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)284 int32_t HiviewServiceAbilityStub::HandleOpenSnapshotTraceRequest(MessageParcel& data, MessageParcel& reply,
285     MessageOption& option)
286 {
287     std::vector<std::string> tagGroups;
288     if (!data.ReadStringVector(&tagGroups)) {
289         HIVIEW_LOGW("failed to read tag groups from parcel");
290         return TraceErrCode::ERR_READ_MSG_PARCEL;
291     }
292     auto ret = OpenSnapshotTrace(tagGroups);
293     return WriteTracePracelableToMessage(reply, ret);
294 }
295 
HandleDumpSnapshotTraceRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)296 int32_t HiviewServiceAbilityStub::HandleDumpSnapshotTraceRequest(MessageParcel& data, MessageParcel& reply,
297     MessageOption& option)
298 {
299     int32_t caller = UCollectClient::TraceCollector::Caller::OTHER;
300     if (!data.ReadInt32(caller)) {
301         HIVIEW_LOGW("failed to read trace caller from parcel");
302         return TraceErrCode::ERR_READ_MSG_PARCEL;
303     }
304     auto ret = DumpSnapshotTrace(caller);
305     return WriteTracePracelableToMessage(reply, ret);
306 }
307 
HandleOpenRecordingTraceRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)308 int32_t HiviewServiceAbilityStub::HandleOpenRecordingTraceRequest(MessageParcel& data, MessageParcel& reply,
309     MessageOption& option)
310 {
311     std::string tags;
312     if (!data.ReadString(tags)) {
313         HIVIEW_LOGW("failed to read tags from parcel");
314         return TraceErrCode::ERR_READ_MSG_PARCEL;
315     }
316     auto ret = OpenRecordingTrace(tags);
317     return WriteTracePracelableToMessage(reply, ret);
318 }
319 
HandleRecordingTraceOnRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)320 int32_t HiviewServiceAbilityStub::HandleRecordingTraceOnRequest(MessageParcel& data, MessageParcel& reply,
321     MessageOption& option)
322 {
323     auto ret = RecordingTraceOn();
324     return WriteTracePracelableToMessage(reply, ret);
325 }
326 
HandleRecordingTraceOffRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)327 int32_t HiviewServiceAbilityStub::HandleRecordingTraceOffRequest(MessageParcel& data, MessageParcel& reply,
328     MessageOption& option)
329 {
330     auto ret = RecordingTraceOff();
331     return WriteTracePracelableToMessage(reply, ret);
332 }
333 
HandleCloseTraceRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)334 int32_t HiviewServiceAbilityStub::HandleCloseTraceRequest(MessageParcel& data, MessageParcel& reply,
335     MessageOption& option)
336 {
337     auto ret = CloseTrace();
338     return WriteTracePracelableToMessage(reply, ret);
339 }
340 
HandleRecoverTraceRequest(MessageParcel & data,MessageParcel & reply,MessageOption & option)341 int32_t HiviewServiceAbilityStub::HandleRecoverTraceRequest(MessageParcel& data, MessageParcel& reply,
342     MessageOption& option)
343 {
344     auto ret = RecoverTrace();
345     return WriteTracePracelableToMessage(reply, ret);
346 }
347 } // namespace HiviewDFX
348 } // namespace OHOS