• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "dslm_ipc_process.h"
17 
18 #include <map>
19 #include <utility>
20 
21 #include "ipc_skeleton.h"
22 #include "iremote_broker.h"
23 #include "securec.h"
24 
25 #include "dslm_callback_info.h"
26 #include "dslm_callback_proxy.h"
27 #include "dslm_core_process.h"
28 #include "utils_log.h"
29 
30 namespace {
31 constexpr uint32_t DFT_TIMEOUT = 45;
32 constexpr uint32_t MAX_TIMEOUT = 60;
33 constexpr uint32_t MIN_TIMEOUT = 1;
34 constexpr uint32_t WARNING_GATE = 64;
35 constexpr uint32_t COOKIE_SHIFT = 32;
36 } // namespace
37 
38 namespace OHOS {
39 namespace Security {
40 namespace DeviceSecurityLevel {
ProcessCallback(uint32_t owner,uint32_t cookie,uint32_t result,const DslmCallbackInfo * info)41 static void ProcessCallback(uint32_t owner, uint32_t cookie, uint32_t result, const DslmCallbackInfo *info)
42 {
43     if ((cookie == 0) || (info == nullptr)) {
44         return;
45     }
46     auto object = Singleton<DslmIpcProcess::RemoteHolder>::GetInstance().Pop(owner, cookie);
47     if (object == nullptr) {
48         SECURITY_LOG_ERROR("Pop failed");
49         return;
50     }
51 
52     auto proxy = iface_cast<DslmCallbackProxy>(object);
53     if (proxy == nullptr) {
54         SECURITY_LOG_ERROR("iface_cast failed");
55         return;
56     }
57     DslmCallbackProxy::ResponseInfo resInfo = {result, info->level, info->extraBuff, info->extraLen};
58     proxy->ResponseDeviceSecurityLevel(cookie, resInfo);
59 }
60 
DslmGetRequestFromParcel(MessageParcel & data,DeviceIdentify & identify,RequestOption & option,sptr<IRemoteObject> & object,uint32_t & cookie)61 int32_t DslmIpcProcess::DslmGetRequestFromParcel(MessageParcel &data, DeviceIdentify &identify, RequestOption &option,
62     sptr<IRemoteObject> &object, uint32_t &cookie)
63 {
64     uint32_t expected = sizeof(DeviceIdentify) + sizeof(RequestOption) + sizeof(uint32_t);
65     uint32_t actual = data.GetReadableBytes();
66     if (expected >= actual) {
67         SECURITY_LOG_ERROR("unexpected input, length error");
68         return ERR_INVALID_PARA;
69     }
70 
71     identify.length = data.ReadUint32();
72 
73     const uint8_t *dataRead = data.ReadBuffer(DEVICE_ID_MAX_LEN);
74     if (dataRead == nullptr) {
75         SECURITY_LOG_ERROR("unexpected input, buffer error");
76         return ERR_INVALID_PARA;
77     }
78     if (memcpy_s(identify.identity, DEVICE_ID_MAX_LEN, dataRead, DEVICE_ID_MAX_LEN) != EOK) {
79         SECURITY_LOG_ERROR("unexpected input, buffer copy error");
80         return ERR_INVALID_PARA;
81     }
82 
83     option.challenge = data.ReadUint64();
84     option.timeout = data.ReadUint32();
85     if (option.timeout < MIN_TIMEOUT || option.timeout > MAX_TIMEOUT) {
86         option.timeout = DFT_TIMEOUT;
87     }
88 
89     option.extra = data.ReadUint32();
90 
91     object = data.ReadRemoteObject();
92     if (object == nullptr) {
93         SECURITY_LOG_ERROR("unexpected input, callback ipc error");
94         return ERR_INVALID_PARA;
95     }
96     cookie = data.ReadUint32();
97     if (cookie == 0) {
98         SECURITY_LOG_ERROR("unexpected input, cookie error");
99         return ERR_INVALID_PARA;
100     }
101 
102     return SUCCESS;
103 }
104 
DslmSetResponseToParcel(MessageParcel & reply,uint32_t status)105 int32_t DslmIpcProcess::DslmSetResponseToParcel(MessageParcel &reply, uint32_t status)
106 {
107     auto success = reply.WriteUint32(status);
108     if (!success) {
109         return ERR_IPC_RET_PARCEL_ERR;
110     }
111     return SUCCESS;
112 }
113 
DslmProcessGetDeviceSecurityLevel(MessageParcel & data,MessageParcel & reply)114 int32_t DslmIpcProcess::DslmProcessGetDeviceSecurityLevel(MessageParcel &data, MessageParcel &reply)
115 {
116     DeviceIdentify identity;
117     RequestOption option;
118     sptr<IRemoteObject> callback;
119     uint32_t cookie;
120 
121     int32_t ret = DslmGetRequestFromParcel(data, identity, option, callback, cookie);
122     if (ret != SUCCESS) {
123         SECURITY_LOG_ERROR("DslmGetRequestFromParcel failed, ret = %{public}d", ret);
124         return ret;
125     }
126 
127     auto owner = IPCSkeleton::GetCallingPid();
128     Singleton<RemoteHolder>::GetInstance().Push(owner, cookie, callback);
129 
130     ret = OnRequestDeviceSecLevelInfo(&identity, &option, owner, cookie, ProcessCallback);
131     if (ret != SUCCESS) {
132         Singleton<RemoteHolder>::GetInstance().Pop(owner, cookie);
133         SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo failed, ret = %{public}d", ret);
134         return ret;
135     }
136 
137     ret = DslmSetResponseToParcel(reply, cookie);
138     if (ret != SUCCESS) {
139         Singleton<RemoteHolder>::GetInstance().Pop(owner, cookie);
140         SECURITY_LOG_ERROR("DslmSetResponseToParcel failed, ret = %{public}d", ret);
141         return ret;
142     }
143     return SUCCESS;
144 }
145 
Push(uint32_t owner,uint32_t cookie,const sptr<IRemoteObject> & object)146 bool DslmIpcProcess::RemoteHolder::Push(uint32_t owner, uint32_t cookie, const sptr<IRemoteObject> &object)
147 {
148     std::lock_guard<std::mutex> lock(mutex_);
149     uint64_t key = (static_cast<uint64_t>(owner) << COOKIE_SHIFT) | cookie;
150     map_[key] = object;
151     if (map_.size() > WARNING_GATE) {
152         SECURITY_LOG_WARN("remote objects max warning");
153     }
154     return true;
155 }
156 
Pop(uint32_t owner,uint32_t cookie)157 sptr<IRemoteObject> DslmIpcProcess::RemoteHolder::Pop(uint32_t owner, uint32_t cookie)
158 {
159     std::lock_guard<std::mutex> lock(mutex_);
160     uint64_t key = (static_cast<uint64_t>(owner) << COOKIE_SHIFT) | cookie;
161     auto iter = map_.find(key);
162     if (iter == map_.end()) {
163         return nullptr;
164     }
165     auto obj = iter->second;
166     map_.erase(iter);
167     return obj;
168 }
169 } // namespace DeviceSecurityLevel
170 } // namespace Security
171 } // namespace OHOS
172