• 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 <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