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 <unistd.h>
21 #include <cstdio>
22 #include <cstdlib>
23 #include <sys/ioctl.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <thread>
27 #include "access_token_adapter.h"
28 #include "ipc_debug.h"
29 #include "string_ex.h"
30 #include "iremote_proxy.h"
31 #include "ipc_skeleton.h"
32 #include "ipc_file_descriptor.h"
33 #include "ipc_test_helper.h"
34 #include "if_system_ability_manager.h"
35 #include "iservice_registry.h"
36 #include "system_ability_definition.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 }
75
ServerSyncTransaction(MessageParcel & data,MessageParcel & reply)76 int32_t TestServiceStub::ServerSyncTransaction(MessageParcel &data, MessageParcel &reply)
77 {
78 int32_t result = 0;
79 int32_t reqData = data.ReadInt32();
80 int32_t delayTime = data.ReadInt32();
81 int32_t ret = TestSyncTransaction(reqData, result, delayTime);
82 reply.WriteInt32(result);
83 return ret;
84 }
85
ServerAsyncTransaction(MessageParcel & data,MessageParcel & reply)86 int32_t TestServiceStub::ServerAsyncTransaction(MessageParcel &data, MessageParcel &reply)
87 {
88 int32_t result = 0;
89 int32_t reqData = data.ReadInt32();
90 int timeout = data.ReadInt32();
91 bool acquireResult = data.ReadBool();
92 if (acquireResult) {
93 sptr<IFoo> fooProxy = iface_cast<IFoo>(data.ReadRemoteObject());
94 if (fooProxy != nullptr) {
95 TestAsyncCallbackTrans(reqData, result, timeout);
96 fooProxy->SendAsyncReply(result);
97 }
98 } else {
99 (void)TestAsyncTransaction(reqData, timeout);
100 }
101 return 0;
102 }
103
ServerPingService(MessageParcel & data,MessageParcel & reply)104 int32_t TestServiceStub::ServerPingService(MessageParcel &data, MessageParcel &reply)
105 {
106 std::u16string serviceName = data.ReadString16();
107 int32_t result = TestPingService(serviceName);
108 ZLOGI(LABEL, "Result:%{public}d", result);
109 reply.WriteInt32(result);
110 return 0;
111 }
112
ServerGetFooService(MessageParcel & data,MessageParcel & reply)113 int32_t TestServiceStub::ServerGetFooService(MessageParcel &data, MessageParcel &reply)
114 {
115 sptr<IFoo> fooService = TestGetFooService();
116 sptr<IRemoteObject> object = fooService->AsObject();
117 object->SetBehavior(Parcelable::BehaviorFlag::HOLD_OBJECT);
118 reply.WriteRemoteObject(object);
119 return 0;
120 }
121
ServerTransactFileDesc(MessageParcel & data,MessageParcel & reply)122 int32_t TestServiceStub::ServerTransactFileDesc(MessageParcel &data, MessageParcel &reply)
123 {
124 int desc = TestGetFileDescriptor();
125 reply.WriteFileDescriptor(desc);
126 close(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 std::map<uint32_t, OHOS::TestServiceStub::TestServiceStubFunc>::iterator it = funcMap_.find(code);
296 if (it != funcMap_.end()) {
297 OHOS::TestServiceStub::TestServiceStubFunc itFunc = it->second;
298 if (itFunc != nullptr) {
299 return (this->*itFunc)(data, reply);
300 }
301 }
302 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
303 }
304
TransferRawData(MessageParcel & data,MessageParcel & reply)305 int32_t TestServiceStub::TransferRawData(MessageParcel &data, MessageParcel &reply)
306 {
307 ZLOGI(LABEL, "Enter transfer raw data");
308 int length = data.ReadInt32();
309 if (length <= 1) {
310 ZLOGE(LABEL, "Length should > 1, length is %{public}d", length);
311 if (!reply.WriteInt32(length)) {
312 ZLOGE(LABEL, "Fail to write parcel");
313 }
314 return ERR_INVALID_DATA;
315 }
316
317 if (!data.ContainFileDescriptors()) {
318 ZLOGE(LABEL, "Sent raw data is less than 32k");
319 }
320
321 const char *buffer = nullptr;
322 if ((buffer = reinterpret_cast<const char *>(data.ReadRawData((size_t)length))) == nullptr) {
323 ZLOGE(LABEL, "Read raw data failed, length = %{public}d", length);
324 if (reply.WriteInt32(0)) {
325 ZLOGE(LABEL, "Fail to write parcel");
326 }
327 return ERR_INVALID_DATA;
328 }
329 if (buffer[0] != 'a' || buffer[length - 1] != 'z') {
330 ZLOGE(LABEL, "Buffer error, length = %{public}d", length);
331 if (reply.WriteInt32(0)) {
332 ZLOGE(LABEL, "Fail to write parcel");
333 }
334 return ERR_INVALID_DATA;
335 }
336 if (data.ReadInt32() != length) {
337 ZLOGE(LABEL, "Read raw data after failed, length = %{public}d", length);
338 if (!reply.WriteInt32(0)) {
339 ZLOGE(LABEL, "Fail to write parcel");
340 }
341 return ERR_INVALID_DATA;
342 }
343 if (!reply.WriteInt32(length)) {
344 ZLOGE(LABEL, "Fail to write parcel");
345 return ERR_INVALID_DATA;
346 }
347 return ERR_NONE;
348 }
349
ReplyRawData(MessageParcel & data,MessageParcel & reply)350 int32_t TestServiceStub::ReplyRawData(MessageParcel &data, MessageParcel &reply)
351 {
352 ZLOGI(LABEL, "Enter reply raw data");
353 int length = data.ReadInt32();
354 if (length <= 1) {
355 ZLOGE(LABEL, "Length should > 1, length is %{public}d", length);
356 if (!reply.WriteInt32(length)) {
357 ZLOGE(LABEL, "Fail to write parcel");
358 }
359 return ERR_INVALID_DATA;
360 }
361
362 unsigned char *buffer = new (std::nothrow) unsigned char[length];
363 if (buffer == nullptr) {
364 ZLOGE(LABEL, "New buffer failed of length = %{public}d", length);
365 return ERR_INVALID_STATE;
366 }
367 buffer[0] = 'a';
368 buffer[length - 1] = 'z';
369 if (!reply.WriteInt32(length) ||
370 !reply.WriteRawData(buffer, (size_t)length) ||
371 !reply.WriteInt32(length)) {
372 ZLOGE(LABEL, "Fail to write parcel");
373 delete [] buffer;
374 return ERR_INVALID_STATE;
375 }
376
377 delete [] buffer;
378 return ERR_NONE;
379 }
380
TransferToNextProcess(MessageParcel & data,MessageParcel & reply)381 int32_t TestServiceStub::TransferToNextProcess(MessageParcel &data, MessageParcel &reply)
382 {
383 int32_t reqData = data.ReadInt32();
384 int32_t delayTime = data.ReadInt32();
385 int result;
386 int ret = TestSyncTransaction(reqData, result, delayTime);
387 reply.WriteInt32(result);
388
389 auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
390 if (saMgr == nullptr) {
391 reply.WriteInt32(ERR_TRANSACTION_FAILED);
392 return ERR_TRANSACTION_FAILED;
393 }
394
395 sptr<IRemoteObject> object = saMgr->GetSystemAbility(IPC_EXTRA_TEST_SERVICE);
396 if (object == nullptr) {
397 reply.WriteInt32(ERR_TRANSACTION_FAILED);
398 return ERR_TRANSACTION_FAILED;
399 }
400
401 sptr<ITestService> testService = iface_cast<ITestService>(object);
402 if (testService == nullptr) {
403 reply.WriteInt32(ERR_TRANSACTION_FAILED);
404 return ERR_TRANSACTION_FAILED;
405 }
406
407 ret += testService->TestSyncTransaction(reqData, result, delayTime);
408 ret += testService->TestAsyncCallbackTrans(reqData, result, delayTime);
409 if (ret != 0) {
410 reply.WriteInt32(ERR_TRANSACTION_FAILED);
411 return ERR_TRANSACTION_FAILED;
412 }
413
414 reply.WriteInt32(ERR_NONE);
415 return ERR_NONE;
416 }
417
ReadAshmem(MessageParcel & data,MessageParcel & reply)418 int32_t TestServiceStub::ReadAshmem(MessageParcel &data, MessageParcel &reply)
419 {
420 int32_t contentSize = data.ReadInt32();
421 if (contentSize < 0) {
422 reply.WriteInt32(-1);
423 return ERR_TRANSACTION_FAILED;
424 }
425
426 sptr<Ashmem> ashmem = data.ReadAshmem();
427 if (ashmem == nullptr) {
428 reply.WriteInt32(-1);
429 return ERR_TRANSACTION_FAILED;
430 }
431
432 int32_t ashmemSize = ashmem->GetAshmemSize();
433 if (ashmemSize < contentSize || !ashmem->MapReadOnlyAshmem()) {
434 reply.WriteInt32(-1);
435 return ERR_TRANSACTION_FAILED;
436 }
437
438 const void *content = ashmem->ReadFromAshmem(contentSize, 0);
439 if (content == nullptr) {
440 reply.WriteInt32(-1);
441 ashmem->UnmapAshmem();
442 ashmem->CloseAshmem();
443 return ERR_TRANSACTION_FAILED;
444 }
445
446 auto pt = static_cast<const char *>(content);
447 std::string str(pt, contentSize);
448 ashmem->UnmapAshmem();
449 ashmem->CloseAshmem();
450
451 std::string name = "ashmem2";
452 sptr<Ashmem> ashmem2 = Ashmem::CreateAshmem(name.c_str(), ashmemSize);
453 if (ashmem2 == nullptr || !ashmem2->MapReadAndWriteAshmem() ||
454 !ashmem2->WriteToAshmem(str.c_str(), contentSize, 0)) {
455 reply.WriteInt32(-1);
456 if (ashmem2 != nullptr) {
457 ashmem2->UnmapAshmem();
458 ashmem2->CloseAshmem();
459 }
460 return ERR_TRANSACTION_FAILED;
461 }
462
463 reply.WriteInt32(contentSize);
464 reply.WriteAshmem(ashmem2);
465
466 ashmem2->UnmapAshmem();
467 ashmem2->CloseAshmem();
468 return ERR_NONE;
469 }
470
ServerFlushAsyncCalls(MessageParcel & data,MessageParcel & reply)471 int32_t TestServiceStub::ServerFlushAsyncCalls(MessageParcel &data, MessageParcel &reply)
472 {
473 (void)data.ReadString16();
474 return ERR_NONE;
475 }
476
477 } // namespace OHOS
478