1 /*
2 * Copyright (c) 2022-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 "res_sched_service_stub.h"
17 #include <cstdint>
18 #include "res_sched_errors.h"
19 #include "res_sched_log.h"
20 #include "res_sched_ipc_interface_code.h"
21 #include "ipc_skeleton.h"
22 #include "ipc_util.h"
23
24 namespace OHOS {
25 namespace ResourceSchedule {
26 namespace {
27 #define PAYLOAD_MAX_SIZE 4096
28
IsValidToken(MessageParcel & data)29 bool IsValidToken(MessageParcel& data)
30 {
31 std::u16string descriptor = ResSchedServiceStub::GetDescriptor();
32 std::u16string remoteDescriptor = data.ReadInterfaceToken();
33 return descriptor == remoteDescriptor;
34 }
35 }
36
ResSchedServiceStub()37 ResSchedServiceStub::ResSchedServiceStub()
38 {
39 Init();
40 }
41
~ResSchedServiceStub()42 ResSchedServiceStub::~ResSchedServiceStub()
43 {
44 }
45
ReportDataInner(MessageParcel & data,MessageParcel & reply)46 int32_t ResSchedServiceStub::ReportDataInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply)
47 {
48 if (!IsValidToken(data)) {
49 return ERR_RES_SCHED_PARCEL_ERROR;
50 }
51 uint32_t type = 0;
52 READ_PARCEL(data, Uint32, type, ERR_RES_SCHED_PARCEL_ERROR, ResSchedServiceStub);
53
54 int64_t value = 0;
55 READ_PARCEL(data, Int64, value, ERR_RES_SCHED_PARCEL_ERROR, ResSchedServiceStub);
56
57 std::string payload;
58 READ_PARCEL(data, String, payload, ERR_RES_SCHED_PARCEL_ERROR, ResSchedServiceStub);
59
60 if (payload.size() <= PAYLOAD_MAX_SIZE) {
61 ReportData(type, value, StringToJsonObj(payload));
62 } else {
63 RESSCHED_LOGE("The payload is too long. DoS.");
64 }
65 return ERR_OK;
66 }
67
KillProcessInner(MessageParcel & data,MessageParcel & reply)68 int32_t ResSchedServiceStub::KillProcessInner(MessageParcel& data, MessageParcel& reply)
69 {
70 if (!IsValidToken(data)) {
71 return ERR_RES_SCHED_PARCEL_ERROR;
72 }
73 std::string payload;
74 READ_PARCEL(data, String, payload, ERR_RES_SCHED_PARCEL_ERROR, ResSchedServiceStub);
75 if (payload.size() <= PAYLOAD_MAX_SIZE) {
76 int32_t status = KillProcess(StringToJsonObj(payload));
77 reply.WriteInt32(status);
78 } else {
79 reply.WriteInt32(RES_SCHED_DATA_ERROR);
80 RESSCHED_LOGE("The payload is too long. DoS.");
81 }
82 return ERR_OK;
83 }
84
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)85 int32_t ResSchedServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
86 MessageParcel &reply, MessageOption &option)
87 {
88 auto uid = IPCSkeleton::GetCallingUid();
89 RESSCHED_LOGD("ResSchedServiceStub::OnRemoteRequest, code = %{public}u, flags = %{public}d,"
90 " uid = %{public}d.", code, option.GetFlags(), uid);
91
92 switch (code) {
93 case static_cast<uint32_t>(ResourceScheduleInterfaceCode::REPORT_DATA):
94 return ReportDataInner(data, reply);
95 case static_cast<uint32_t>(ResourceScheduleInterfaceCode::KILL_PROCESS):
96 return KillProcessInner(data, reply);
97 default:
98 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
99 }
100 }
101
StringToJsonObj(const std::string & payload)102 nlohmann::json ResSchedServiceStub::StringToJsonObj(const std::string& payload)
103 {
104 nlohmann::json jsonObj = nlohmann::json::object();
105 if (payload.empty()) {
106 return jsonObj;
107 }
108 nlohmann::json jsonTmp = nlohmann::json::parse(payload, nullptr, false);
109 if (jsonTmp.is_discarded()) {
110 RESSCHED_LOGE("%{public}s parse payload to json failed: %{public}s.", __func__, payload.c_str());
111 return jsonObj;
112 }
113 if (!jsonTmp.is_object()) {
114 RESSCHED_LOGE("%{public}s payload converted result is not a jsonObj: %{public}s.", __func__, payload.c_str());
115 return jsonObj;
116 }
117 return jsonTmp;
118 }
119
Init()120 void ResSchedServiceStub::Init()
121 {
122 }
123 } // namespace ResourceSchedule
124 } // namespace OHOS
125