1 /*
2 * Copyright (C) 2024 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 "test_service_stub.h"
17 #include <cinttypes>
18 #include <fcntl.h>
19 #include <iostream>
20 #include <cstdio>
21 #include <cstdlib>
22 #include <sys/ioctl.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <thread>
26 #include "access_token_adapter.h"
27 #include "ipc_debug.h"
28 #include "string_ex.h"
29 #include "iremote_proxy.h"
30 #include "ipc_skeleton.h"
31 #include "ipc_file_descriptor.h"
32 #include "ipc_test_helper.h"
33 #include "if_system_ability_manager.h"
34 #include "iservice_registry.h"
35 #include "system_ability_definition.h"
36 #include "fd_san.h"
37
38 namespace OHOS {
39 using namespace OHOS::HiviewDFX;
40
41 constexpr int32_t MAX_RECURSIVE_SENDS = 5;
42
TestServiceStub(bool serialInvokeFlag)43 TestServiceStub::TestServiceStub(bool serialInvokeFlag)
44 : IRemoteStub(serialInvokeFlag), serialInvokeFlag_(serialInvokeFlag)
45 {
46 InitMessageProcessMap();
47 }
48
InitMessageProcessMap()49 void TestServiceStub::InitMessageProcessMap()
50 {
51 funcMap_[static_cast<uint32_t>(TRANS_ID_SYNC_TRANSACTION)] = &TestServiceStub::ServerSyncTransaction;
52 funcMap_[static_cast<uint32_t>(TRANS_ID_ASYNC_TRANSACTION)] = &TestServiceStub::ServerAsyncTransaction;
53 funcMap_[static_cast<uint32_t>(TRANS_ID_PING_SERVICE)] = &TestServiceStub::ServerPingService;
54 funcMap_[static_cast<uint32_t>(TRANS_ID_GET_FOO_SERVICE)] = &TestServiceStub::ServerGetFooService;
55 funcMap_[static_cast<uint32_t>(TRANS_ID_TRANSACT_FILE_DESC)] = &TestServiceStub::ServerTransactFileDesc;
56 funcMap_[static_cast<uint32_t>(TRANS_ID_STRING_TRANSACTION)] = &TestServiceStub::ServerStringTransaction;
57 funcMap_[static_cast<uint32_t>(TRANS_ID_ZTRACE_TRANSACTION)] = &TestServiceStub::ServerZtraceTransaction;
58 funcMap_[static_cast<uint32_t>(TRANS_ID_RAWDATA_TRANSACTION)] = &TestServiceStub::TransferRawData;
59 funcMap_[static_cast<uint32_t>(TRANS_ID_RAWDATA_REPLY)] = &TestServiceStub::ReplyRawData;
60 funcMap_[static_cast<uint32_t>(TRANS_ID_FLUSH_ASYNC_CALLS)] = &TestServiceStub::ServerFlushAsyncCalls;
61 funcMap_[static_cast<uint32_t>(TRANS_ID_ASHMEM)] = &TestServiceStub::ReadAshmem;
62 funcMap_[static_cast<uint32_t>(TRANS_ID_MULTIPLE_PROCESSES)] = &TestServiceStub::TransferToNextProcess;
63 funcMap_[static_cast<uint32_t>(TRANS_ID_CALLING_UID_PID)] = &TestServiceStub::ServerCallingUidAndPid;
64 funcMap_[static_cast<uint32_t>(TRANS_ID_NESTING_SEND)] = &TestServiceStub::ServerNestingSend;
65 funcMap_[static_cast<uint32_t>(TRANS_ID_ACCESS_TOKENID)] = &TestServiceStub::ServerAccessTokenId;
66 funcMap_[static_cast<uint32_t>(TRANS_ID_ACCESS_TOKENID_64)] = &TestServiceStub::ServerAccessTokenId64;
67 funcMap_[static_cast<uint32_t>(TRANS_MESSAGE_PARCEL_ADDPED)] = &TestServiceStub::ServerMessageParcelAddped;
68 funcMap_[static_cast<uint32_t>(TRANS_MESSAGE_PARCEL_ADDPED_WITH_OBJECT)] =
69 &TestServiceStub::ServerMessageParcelAddpedWithObject;
70 funcMap_[static_cast<uint32_t>(TRANS_ENABLE_SERIAL_INVOKE_FLAG)] = &TestServiceStub::ServerEnableSerialInvokeFlag;
71 funcMap_[static_cast<uint32_t>(TRANS_ID_REGISTER_REMOTE_STUB_OBJECT)] = &TestServiceStub::RegisterRemoteStub;
72 funcMap_[static_cast<uint32_t>(TRANS_ID_UNREGISTER_REMOTE_STUB_OBJECT)] = &TestServiceStub::UnRegisterRemoteStub;
73 funcMap_[static_cast<uint32_t>(TRANS_ID_QUERY_REMOTE_PROXY_OBJECT)] = &TestServiceStub::QueryRemoteProxy;
74 funcMap_[static_cast<uint32_t>(TRANS_ID_QUERY_THREAD_INVOCATION_STATE)] = &TestServiceStub::ServerThreadInvocationState;
75 }
76
ServerSyncTransaction(MessageParcel & data,MessageParcel & reply)77 int32_t TestServiceStub::ServerSyncTransaction(MessageParcel &data, MessageParcel &reply)
78 {
79 int32_t result = 0;
80 int32_t reqData = data.ReadInt32();
81 int32_t delayTime = data.ReadInt32();
82 int32_t ret = TestSyncTransaction(reqData, result, delayTime);
83 reply.WriteInt32(result);
84 return ret;
85 }
86
ServerAsyncTransaction(MessageParcel & data,MessageParcel & reply)87 int32_t TestServiceStub::ServerAsyncTransaction(MessageParcel &data, MessageParcel &reply)
88 {
89 int32_t result = 0;
90 int32_t reqData = data.ReadInt32();
91 int timeout = data.ReadInt32();
92 bool acquireResult = data.ReadBool();
93 if (acquireResult) {
94 sptr<IFoo> fooProxy = iface_cast<IFoo>(data.ReadRemoteObject());
95 if (fooProxy != nullptr) {
96 TestAsyncCallbackTrans(reqData, result, timeout);
97 fooProxy->SendAsyncReply(result);
98 }
99 } else {
100 (void)TestAsyncTransaction(reqData, timeout);
101 }
102 return 0;
103 }
104
ServerPingService(MessageParcel & data,MessageParcel & reply)105 int32_t TestServiceStub::ServerPingService(MessageParcel &data, MessageParcel &reply)
106 {
107 std::u16string serviceName = data.ReadString16();
108 int32_t result = TestPingService(serviceName);
109 ZLOGI(LABEL, "Result:%{public}d", result);
110 reply.WriteInt32(result);
111 return 0;
112 }
113
ServerGetFooService(MessageParcel & data,MessageParcel & reply)114 int32_t TestServiceStub::ServerGetFooService(MessageParcel &data, MessageParcel &reply)
115 {
116 sptr<IFoo> fooService = TestGetFooService();
117 sptr<IRemoteObject> object = fooService->AsObject();
118 object->SetBehavior(Parcelable::BehaviorFlag::HOLD_OBJECT);
119 reply.WriteRemoteObject(object);
120 return 0;
121 }
122
ServerTransactFileDesc(MessageParcel & data,MessageParcel & reply)123 int32_t TestServiceStub::ServerTransactFileDesc(MessageParcel &data, MessageParcel &reply)
124 {
125 int desc = TestGetFileDescriptor();
126 reply.WriteFileDescriptor(desc);
127 return 0;
128 }
129
ServerStringTransaction(MessageParcel & data,MessageParcel & reply)130 int32_t TestServiceStub::ServerStringTransaction(MessageParcel &data, MessageParcel &reply)
131 {
132 const std::string testString = data.ReadString();
133 int testSize = TestStringTransaction(testString);
134 reply.WriteInt32(testSize);
135 reply.WriteString(testString);
136 return 0;
137 }
138
ServerZtraceTransaction(MessageParcel & data,MessageParcel & reply)139 int32_t TestServiceStub::ServerZtraceTransaction(MessageParcel &data, MessageParcel &reply)
140 {
141 int32_t ret = 0;
142 int32_t len = data.ReadInt32();
143 if (len < 0) {
144 ZLOGE(LABEL, "Get len failed, len = %{public}d", len);
145 return ret;
146 }
147 std::string recvString;
148 std::string replyString(len, 0);
149 recvString = data.ReadString();
150 ret = TestZtraceTransaction(recvString, replyString, len);
151 if (!ret) {
152 reply.WriteString(replyString);
153 }
154 return ret;
155 }
156
ServerCallingUidAndPid(MessageParcel & data,MessageParcel & reply)157 int32_t TestServiceStub::ServerCallingUidAndPid(MessageParcel &data, MessageParcel &reply)
158 {
159 reply.WriteInt32(IPCSkeleton::GetCallingUid());
160 reply.WriteInt32(IPCSkeleton::GetCallingPid());
161
162 ZLOGI(LABEL, "Calling before reset uid = %{public}d, pid = %{public}d",
163 IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid());
164 std::string token = IPCSkeleton::ResetCallingIdentity();
165
166 ZLOGI(LABEL, "Calling before set uid = %{public}d, pid = %{public}d",
167 IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid());
168 if (!IPCSkeleton::SetCallingIdentity(token)) {
169 ZLOGE(LABEL, "Set Calling Identity fail");
170 return 0;
171 }
172
173 ZLOGI(LABEL, "Calling after set uid = %{public}d, pid = %{public}d",
174 IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid());
175 return 0;
176 }
177
ServerNestingSend(MessageParcel & data,MessageParcel & reply)178 int32_t TestServiceStub::ServerNestingSend(MessageParcel &data, MessageParcel &reply)
179 {
180 sptr<IRemoteObject> object = data.ReadRemoteObject();
181 if (object == nullptr) {
182 ZLOGE(LABEL, "object is nullptr");
183 return -1;
184 }
185 sptr<IFoo> foo = iface_cast<IFoo>(object);
186 if (foo == nullptr) {
187 ZLOGE(LABEL, "foo is nullptr");
188 return -1;
189 }
190 int innerResult = foo->TestNestingSend(data.ReadInt32());
191 reply.WriteInt32(innerResult);
192 return 0;
193 }
194
ServerAccessTokenId(MessageParcel & data,MessageParcel & reply)195 int32_t TestServiceStub::ServerAccessTokenId(MessageParcel &data, MessageParcel &reply)
196 {
197 int32_t token = static_cast<int32_t>(IPCSkeleton::GetCallingTokenID());
198 int32_t ftoken = static_cast<int32_t>(IPCSkeleton::GetFirstTokenID());
199 ZLOGI(LABEL, "Server GetCallingTokenID:%{public}d", token);
200 ZLOGI(LABEL, "Server GetFirstTokenID:%{public}d", ftoken);
201 reply.WriteInt32(token);
202 reply.WriteInt32(ftoken);
203 return 0;
204 }
205
ServerAccessTokenId64(MessageParcel & data,MessageParcel & reply)206 int32_t TestServiceStub::ServerAccessTokenId64(MessageParcel &data, MessageParcel &reply)
207 {
208 uint64_t token = IPCSkeleton::GetCallingFullTokenID();
209 uint64_t ftoken = IPCSkeleton::GetFirstFullTokenID();
210 ZLOGI(LABEL, "Server GetCallingFullTokenID:%{public}" PRIu64, token);
211 ZLOGI(LABEL, "Server GetFirstFullTokenID:%{public}" PRIu64, ftoken);
212 reply.WriteUint64(token);
213 reply.WriteUint64(ftoken);
214 return 0;
215 }
216
ServerMessageParcelAddped(MessageParcel & data,MessageParcel & reply)217 int32_t TestServiceStub::ServerMessageParcelAddped(MessageParcel &data, MessageParcel &reply)
218 {
219 reply.WriteInt32(data.ReadInt32());
220 reply.WriteInt32(data.ReadInt32());
221 reply.WriteString(data.ReadString());
222 return 0;
223 }
224
ServerMessageParcelAddpedWithObject(MessageParcel & data,MessageParcel & reply)225 int32_t TestServiceStub::ServerMessageParcelAddpedWithObject(MessageParcel &data, MessageParcel &reply)
226 {
227 reply.WriteInt32(data.ReadInt32());
228 reply.WriteInt32(data.ReadInt32());
229 reply.WriteString(data.ReadString());
230 reply.WriteRemoteObject(data.ReadRemoteObject());
231 reply.WriteFileDescriptor(data.ReadFileDescriptor());
232 return 0;
233 }
234
ServerEnableSerialInvokeFlag(MessageParcel & data,MessageParcel & reply)235 int32_t TestServiceStub::ServerEnableSerialInvokeFlag(MessageParcel &data, MessageParcel &reply)
236 {
237 int32_t ret = 0;
238 static int sendCount = 0;
239
240 if (sendCount == 0) {
241 if (serialInvokeFlag_) {
242 ZLOGI(LABEL, "Enable serial invoke flag");
243 } else {
244 ZLOGI(LABEL, "Not enable serial invoke flag");
245 }
246 }
247
248 reply.WriteString(data.ReadString());
249 sendCount++;
250
251 if (sendCount >= MAX_RECURSIVE_SENDS) {
252 return ret;
253 }
254
255 MessageOption option;
256 MessageParcel dataParcel;
257 MessageParcel replyParcel;
258 std::string value = std::to_string(sendCount); // The last time was 4.
259
260 std::thread::id id_1 = std::this_thread::get_id();
261 ZLOGI(LABEL, "Current thread ID = %{public}u", *(unsigned int*)&id_1);
262 ZLOGI(LABEL, "Send to server data = %{public}s", value.c_str());
263 dataParcel.WriteString(value);
264 ret = IPCObjectStub::SendRequest(TRANS_ENABLE_SERIAL_INVOKE_FLAG, dataParcel, replyParcel, option);
265 std::string result = replyParcel.ReadString();
266
267 std::thread::id id_2 = std::this_thread::get_id();
268 ZLOGI(LABEL, "Current thread ID = %{public}u", *(unsigned int*)&id_2);
269 ZLOGI(LABEL, "Get result from server data = %{public}s", result.c_str());
270 return ret;
271 }
272
RegisterRemoteStub(MessageParcel & data,MessageParcel & reply)273 int32_t TestServiceStub::RegisterRemoteStub(MessageParcel &data, MessageParcel &reply)
274 {
275 std::string descriptor = data.ReadString();
276 auto remoteObject = data.ReadRemoteObject();
277 return TestRegisterRemoteStub(descriptor.c_str(), remoteObject);
278 }
279
UnRegisterRemoteStub(MessageParcel & data,MessageParcel & reply)280 int32_t TestServiceStub::UnRegisterRemoteStub(MessageParcel &data, MessageParcel &reply)
281 {
282 std::string descriptor = data.ReadString();
283 return TestUnRegisterRemoteStub(descriptor.c_str());
284 }
285
QueryRemoteProxy(MessageParcel & data,MessageParcel & reply)286 int32_t TestServiceStub::QueryRemoteProxy(MessageParcel &data, MessageParcel &reply)
287 {
288 std::string descriptor = data.ReadString();
289 sptr<IRemoteObject> remoteObject = TestQueryRemoteProxy(descriptor.c_str());
290 return reply.WriteRemoteObject(remoteObject);
291 }
292
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)293 int TestServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
294 {
295 int state = IPCSkeleton::GetThreadInvocationState();
296 ZLOGI(LABEL, "Thread state = %{public}d, cmd = %{public}u", state, code);
297
298 std::map<uint32_t, OHOS::TestServiceStub::TestServiceStubFunc>::iterator it = funcMap_.find(code);
299 if (it != funcMap_.end()) {
300 OHOS::TestServiceStub::TestServiceStubFunc itFunc = it->second;
301 if (itFunc != nullptr) {
302 return (this->*itFunc)(data, reply);
303 }
304 }
305 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
306 }
307
TransferRawData(MessageParcel & data,MessageParcel & reply)308 int32_t TestServiceStub::TransferRawData(MessageParcel &data, MessageParcel &reply)
309 {
310 ZLOGI(LABEL, "Enter transfer raw data");
311 int length = data.ReadInt32();
312 if (length <= 1) {
313 ZLOGE(LABEL, "Length should > 1, length is %{public}d", length);
314 if (!reply.WriteInt32(length)) {
315 ZLOGE(LABEL, "Fail to write parcel");
316 }
317 return ERR_INVALID_DATA;
318 }
319
320 if (!data.ContainFileDescriptors()) {
321 ZLOGE(LABEL, "Sent raw data is less than 32k");
322 }
323
324 const char *buffer = nullptr;
325 if ((buffer = reinterpret_cast<const char *>(data.ReadRawData((size_t)length))) == nullptr) {
326 ZLOGE(LABEL, "Read raw data failed, length = %{public}d", length);
327 if (reply.WriteInt32(0)) {
328 ZLOGE(LABEL, "Fail to write parcel");
329 }
330 return ERR_INVALID_DATA;
331 }
332 if (buffer[0] != 'a' || buffer[length - 1] != 'z') {
333 ZLOGE(LABEL, "Buffer error, length = %{public}d", length);
334 if (reply.WriteInt32(0)) {
335 ZLOGE(LABEL, "Fail to write parcel");
336 }
337 return ERR_INVALID_DATA;
338 }
339 if (data.ReadInt32() != length) {
340 ZLOGE(LABEL, "Read raw data after failed, length = %{public}d", length);
341 if (!reply.WriteInt32(0)) {
342 ZLOGE(LABEL, "Fail to write parcel");
343 }
344 return ERR_INVALID_DATA;
345 }
346 if (!reply.WriteInt32(length)) {
347 ZLOGE(LABEL, "Fail to write parcel");
348 return ERR_INVALID_DATA;
349 }
350 return ERR_NONE;
351 }
352
ReplyRawData(MessageParcel & data,MessageParcel & reply)353 int32_t TestServiceStub::ReplyRawData(MessageParcel &data, MessageParcel &reply)
354 {
355 ZLOGI(LABEL, "Enter reply raw data");
356 int length = data.ReadInt32();
357 if (length <= 1) {
358 ZLOGE(LABEL, "Length should > 1, length is %{public}d", length);
359 if (!reply.WriteInt32(length)) {
360 ZLOGE(LABEL, "Fail to write parcel");
361 }
362 return ERR_INVALID_DATA;
363 }
364
365 unsigned char *buffer = new (std::nothrow) unsigned char[length];
366 if (buffer == nullptr) {
367 ZLOGE(LABEL, "New buffer failed of length = %{public}d", length);
368 return ERR_INVALID_STATE;
369 }
370 buffer[0] = 'a';
371 buffer[length - 1] = 'z';
372 if (!reply.WriteInt32(length) ||
373 !reply.WriteRawData(buffer, (size_t)length) ||
374 !reply.WriteInt32(length)) {
375 ZLOGE(LABEL, "Fail to write parcel");
376 delete [] buffer;
377 return ERR_INVALID_STATE;
378 }
379
380 delete [] buffer;
381 return ERR_NONE;
382 }
383
TransferToNextProcess(MessageParcel & data,MessageParcel & reply)384 int32_t TestServiceStub::TransferToNextProcess(MessageParcel &data, MessageParcel &reply)
385 {
386 int32_t reqData = data.ReadInt32();
387 int32_t delayTime = data.ReadInt32();
388 int result;
389 int ret = TestSyncTransaction(reqData, result, delayTime);
390 reply.WriteInt32(result);
391
392 auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
393 if (saMgr == nullptr) {
394 reply.WriteInt32(ERR_TRANSACTION_FAILED);
395 return ERR_TRANSACTION_FAILED;
396 }
397
398 sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_EXTRA_TEST_SERVICE);
399 if (object == nullptr) {
400 reply.WriteInt32(ERR_TRANSACTION_FAILED);
401 return ERR_TRANSACTION_FAILED;
402 }
403
404 sptr<ITestService> testService = iface_cast<ITestService>(object);
405 if (testService == nullptr) {
406 reply.WriteInt32(ERR_TRANSACTION_FAILED);
407 return ERR_TRANSACTION_FAILED;
408 }
409
410 ret += testService->TestSyncTransaction(reqData, result, delayTime);
411 ret += testService->TestAsyncCallbackTrans(reqData, result, delayTime);
412 if (ret != 0) {
413 reply.WriteInt32(ERR_TRANSACTION_FAILED);
414 return ERR_TRANSACTION_FAILED;
415 }
416
417 reply.WriteInt32(ERR_NONE);
418 return ERR_NONE;
419 }
420
ReadAshmem(MessageParcel & data,MessageParcel & reply)421 int32_t TestServiceStub::ReadAshmem(MessageParcel &data, MessageParcel &reply)
422 {
423 int32_t contentSize = data.ReadInt32();
424 if (contentSize < 0) {
425 reply.WriteInt32(-1);
426 return ERR_TRANSACTION_FAILED;
427 }
428
429 sptr<Ashmem> ashmem = data.ReadAshmem();
430 if (ashmem == nullptr) {
431 reply.WriteInt32(-1);
432 return ERR_TRANSACTION_FAILED;
433 }
434
435 int32_t ashmemSize = ashmem->GetAshmemSize();
436 if (ashmemSize < contentSize || !ashmem->MapReadOnlyAshmem()) {
437 reply.WriteInt32(-1);
438 return ERR_TRANSACTION_FAILED;
439 }
440
441 const void *content = ashmem->ReadFromAshmem(contentSize, 0);
442 if (content == nullptr) {
443 reply.WriteInt32(-1);
444 ashmem->UnmapAshmem();
445 ashmem->CloseAshmem();
446 return ERR_TRANSACTION_FAILED;
447 }
448
449 auto pt = static_cast<const char *>(content);
450 std::string str(pt, contentSize);
451 ashmem->UnmapAshmem();
452 ashmem->CloseAshmem();
453
454 std::string name = "ashmem2";
455 sptr<Ashmem> ashmem2 = Ashmem::CreateAshmem(name.c_str(), ashmemSize);
456 if (ashmem2 == nullptr || !ashmem2->MapReadAndWriteAshmem() ||
457 !ashmem2->WriteToAshmem(str.c_str(), contentSize, 0)) {
458 reply.WriteInt32(-1);
459 if (ashmem2 != nullptr) {
460 ashmem2->UnmapAshmem();
461 ashmem2->CloseAshmem();
462 }
463 return ERR_TRANSACTION_FAILED;
464 }
465
466 reply.WriteInt32(contentSize);
467 reply.WriteAshmem(ashmem2);
468
469 ashmem2->UnmapAshmem();
470 ashmem2->CloseAshmem();
471 return ERR_NONE;
472 }
473
ServerFlushAsyncCalls(MessageParcel & data,MessageParcel & reply)474 int32_t TestServiceStub::ServerFlushAsyncCalls(MessageParcel &data, MessageParcel &reply)
475 {
476 (void)data.ReadString16();
477 return ERR_NONE;
478 }
479
ServerThreadInvocationState(MessageParcel & data,MessageParcel & reply)480 int32_t TestServiceStub::ServerThreadInvocationState(MessageParcel &data, MessageParcel &reply)
481 {
482 int32_t ret = TestQueryThreadInvocationState();
483 reply.WriteInt32(ret);
484 return ret;
485 }
486 } // namespace OHOS
487