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