• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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