• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "dslm_inner_process.h"
17 
18 #include "dslm_callback_info.h"
19 #include "dslm_core_process.h"
20 #include "securec.h"
21 #include "utils_dslm_list.h"
22 #include "utils_log.h"
23 #include "utils_mem.h"
24 #include "utils_mutex.h"
25 
26 #define DFT_TIMEOUT 45
27 const uint32_t MAX_TIMEOUT = 60;
28 const uint32_t MIN_TIMEOUT = 1;
29 const uint32_t WARNING_GATE = 64;
30 const uint32_t COOKIE_SHIFT = 32;
31 const uint32_t SINGLE_OWNER = 7;
32 
GetRemoteStubList(void)33 static DslmRemoteStubList *GetRemoteStubList(void)
34 {
35     static DslmRemoteStubListNode head = {.node = INIT_LIST(head.node), .key = 0, .callback = NULL, .identify = NULL};
36     static Mutex mutex = INITED_MUTEX;
37     static DslmRemoteStubList stubList = {.head = &head, .size = 0, .mutex = &mutex};
38     return &stubList;
39 }
40 
SetRemoteStubStatus(DeviceIdentify * identity,DeviceSecurityInfoCallback callback,int32_t status)41 static void SetRemoteStubStatus(DeviceIdentify *identity, DeviceSecurityInfoCallback callback, int32_t status)
42 {
43     if (identity == NULL || callback == NULL) {
44         SECURITY_LOG_ERROR("unexpected input");
45         return;
46     }
47     DeviceSecurityInfo *resultInfo = (DeviceSecurityInfo *)MALLOC(sizeof(DeviceSecurityInfo));
48     if (resultInfo == NULL) {
49         SECURITY_LOG_ERROR("no memory");
50         return;
51     }
52     resultInfo->magicNum = SECURITY_MAGIC;
53     resultInfo->result = status;
54     resultInfo->level = 0;
55     SECURITY_LOG_ERROR("RequestDeviceSecurityLevelSendRequest result value error");
56     SECURITY_LOG_INFO("calling user callback");
57     callback(identity, resultInfo);
58 }
59 
DslmPushRemoteStub(uint32_t owner,uint32_t cookie,const DeviceIdentify * identify,DeviceSecurityInfoCallback callback)60 static BOOL DslmPushRemoteStub(uint32_t owner, uint32_t cookie, const DeviceIdentify *identify,
61     DeviceSecurityInfoCallback callback)
62 {
63     if (GetRemoteStubList()->size > WARNING_GATE) {
64         SECURITY_LOG_WARN("remote objects max warning");
65     }
66     uint64_t key = ((uint64_t)owner << COOKIE_SHIFT) | cookie;
67     DslmRemoteStubListNode *item = (DslmRemoteStubListNode *)MALLOC(sizeof(DslmRemoteStubListNode));
68     if (item == NULL) {
69         SECURITY_LOG_ERROR("malloc failed, node is null");
70         return false;
71     }
72     memset_s(item, sizeof(DslmRemoteStubListNode), 0, sizeof(DslmRemoteStubListNode));
73 
74     item->key = key;
75     item->callback = callback;
76     item->identify = identify;
77     LockMutex(GetRemoteStubList()->mutex);
78     AddListNode(&item->node, &GetRemoteStubList()->head->node);
79     GetRemoteStubList()->size++;
80     UnlockMutex(GetRemoteStubList()->mutex);
81     return true;
82 }
83 
DslmPopRemoteStub(uint32_t owner,uint32_t cookie)84 static DslmRemoteStubListNode *DslmPopRemoteStub(uint32_t owner, uint32_t cookie)
85 {
86     ListNode *node = NULL;
87     ListNode *temp = NULL;
88     DslmRemoteStubListNode *item = NULL;
89     DslmRemoteStubListNode *find = NULL;
90 
91     LockMutex(GetRemoteStubList()->mutex);
92     uint64_t key = ((uint64_t)owner << COOKIE_SHIFT) | cookie;
93     FOREACH_LIST_NODE_SAFE (node, &GetRemoteStubList()->head->node, temp) {
94         item = LIST_ENTRY(node, DslmRemoteStubListNode, node);
95         if (item->key == key) {
96             SECURITY_LOG_INFO("pop remote stub");
97             find = item;
98             RemoveListNode(node);
99             if (GetRemoteStubList()->size > 0) {
100                 GetRemoteStubList()->size--;
101             } else {
102                 SECURITY_LOG_ERROR("list size is abnormal, size = %u", GetRemoteStubList()->size);
103             }
104             break;
105         }
106     }
107     UnlockMutex(GetRemoteStubList()->mutex);
108     return find;
109 }
110 
ProcessCallback(uint32_t owner,uint32_t cookie,uint32_t result,const DslmCallbackInfo * info)111 static void ProcessCallback(uint32_t owner, uint32_t cookie, uint32_t result, const DslmCallbackInfo *info)
112 {
113     if ((cookie == 0) || (info == NULL)) {
114         return;
115     }
116 
117     DslmRemoteStubListNode *item = DslmPopRemoteStub(owner, cookie);
118     if (item == NULL || item->callback == NULL) {
119         SECURITY_LOG_ERROR("malformed item");
120         return;
121     }
122 
123     DeviceSecurityInfo *resultInfo = (DeviceSecurityInfo *)MALLOC(sizeof(DeviceSecurityInfo));
124     if (resultInfo == NULL) {
125         SECURITY_LOG_ERROR("no memory");
126         return;
127     }
128     resultInfo->magicNum = SECURITY_MAGIC;
129     resultInfo->result = result;
130     resultInfo->level = info->level;
131     SECURITY_LOG_INFO("calling user callback");
132     item->callback(item->identify, resultInfo);
133     FREE(item);
134     SECURITY_LOG_INFO("process callback succ");
135 }
136 
DslmProcessGetDeviceSecurityLevel(IUnknown * iUnknown,DslmAsyncCallParams * req,DeviceSecurityInfoCallback callback)137 int32_t DslmProcessGetDeviceSecurityLevel(IUnknown *iUnknown, DslmAsyncCallParams *req,
138     DeviceSecurityInfoCallback callback)
139 {
140     if (req == NULL || callback == NULL) {
141         SECURITY_LOG_ERROR("invalid input");
142         return ERR_INVALID_PARA;
143     }
144 
145     uint64_t owner = SINGLE_OWNER;
146     DslmPushRemoteStub(owner, req->cookie, req->identity, callback);
147     int32_t ret = OnRequestDeviceSecLevelInfo(req->identity, req->option, owner, req->cookie, ProcessCallback);
148     if (ret != SUCCESS) {
149         SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo failed, ret = %d", ret);
150         SetRemoteStubStatus(req->identity, callback, ret);
151         DslmRemoteStubListNode *item = DslmPopRemoteStub(owner, req->cookie);
152         if (item != NULL) {
153             FREE(item);
154         }
155         return ret;
156     }
157     return SUCCESS;
158 }