• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 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 #include "endpoint.h"
16 
17 #include <log.h>
18 #include <ohos_errno.h>
19 #include <securec.h>
20 #include <service.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 
24 #include "default_client.h"
25 #include "ipc_skeleton.h"
26 #include "iproxy_server.h"
27 #include "memory_adapter.h"
28 #include "policy_define.h"
29 #include "pthread.h"
30 #include "samgr_server.h"
31 #include "serializer.h"
32 #include "thread_adapter.h"
33 
34 typedef struct RemoteRegister RemoteRegister;
35 struct RemoteRegister {
36     MutexId mtx;
37     Endpoint *endpoint;
38     Vector clients;
39 };
40 
41 #undef LOG_TAG
42 #undef LOG_DOMAIN
43 #define LOG_TAG "Samgr"
44 #define LOG_DOMAIN 0xD001800
45 
46 #ifdef LITE_LINUX_BINDER_IPC
47 #define MAX_STACK_SIZE 0x100000
48 #else
49 #define MAX_STACK_SIZE 0x1000
50 #endif
51 #define MAX_OBJECT_NUM 5
52 #define MAX_RETRY_TIMES 300
53 #define RETRY_INTERVAL (50 * 1000)
54 #define MAX_REGISTER_RETRY_TIMES 10
55 #define REGISTER_RETRY_INTERVAL 2
56 #define MAX_POLICY_NUM 8
57 
58 #ifndef MAX_BUCKET_RATE
59 #define MAX_BUCKET_RATE 1000
60 #endif
61 
62 #ifndef MAX_BURST_RATE
63 #define MAX_BURST_RATE (MAX_BUCKET_RATE + (MAX_BUCKET_RATE >> 1))
64 #endif
65 
66 #define SAMGR_SERVICE "samgr"
67 
68 typedef struct Router {
69     SaName saName;
70     Identity identity;
71     IServerProxy *proxy;
72     PolicyTrans *policy;
73     uint32 policyNum;
74 } Router;
75 
76 static int CompareIServerProxy(const IServerProxy *proxy1, const IServerProxy *proxy2);
77 static IServerProxy *GetIServerProxy(const Router *router);
78 static int Dispatch(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option);
79 static void HandleIpc(const Request *request, const Response *response);
80 static int OnSamgrServerExit(void *ipcMsg, IpcIo *data, void *argv);
81 static int RegisterRemoteFeatures(Endpoint *endpoint);
82 static void Listen(Endpoint *endpoint, int index, const char *service, const char *feature);
83 static boolean JudgePolicy(uid_t callingUid, const PolicyTrans *policy, uint32 policyNum);
84 static boolean SearchFixedPolicy(uid_t callingUid, PolicyTrans policy);
85 static int AddPolicyToRouter(const Endpoint *endpoint, const SvcIdentity *saInfo,
86                              const PolicyTrans *policy, uint32 policyNum);
87 static int RegisterRemoteEndpoint(SvcIdentity *identity, int token, const char *service, const char *feature);
88 static int RegisterIdentity(const SaName *saName, SvcIdentity *saInfo,
89                             PolicyTrans **policy, uint32 *policyNum);
90 static void GetRemotePolicy(IpcIo *reply, PolicyTrans **policy, uint32 *policyNum);
91 
SAMGR_CreateEndpoint(const char * name,RegisterEndpoint registry)92 Endpoint *SAMGR_CreateEndpoint(const char *name, RegisterEndpoint registry)
93 {
94     Endpoint *endpoint = SAMGR_Malloc(sizeof(Endpoint));
95     if (endpoint == NULL) {
96         return NULL;
97     }
98     endpoint->deadId = INVALID_INDEX;
99     endpoint->boss = NULL;
100     endpoint->routers = VECTOR_Make((VECTOR_Key)GetIServerProxy, (VECTOR_Compare)CompareIServerProxy);
101     endpoint->name = name;
102     endpoint->running = FALSE;
103     endpoint->identity.handle = (uint32_t)INVALID_INDEX;
104     endpoint->identity.token = (uint32_t)INVALID_INDEX;
105     endpoint->identity.cookie = (uint32_t)INVALID_INDEX;
106     endpoint->registerEP = (registry == NULL) ? RegisterRemoteEndpoint : registry;
107     TB_InitBucket(&endpoint->bucket, MAX_BUCKET_RATE, MAX_BURST_RATE);
108     return endpoint;
109 }
110 
SAMGR_AddRouter(Endpoint * endpoint,const SaName * saName,const Identity * id,IUnknown * proxy)111 int SAMGR_AddRouter(Endpoint *endpoint, const SaName *saName, const Identity *id, IUnknown *proxy)
112 {
113     if (endpoint == NULL || id == NULL || proxy == NULL || saName == NULL) {
114         return EC_INVALID;
115     }
116     printf("%s %d %d\n", __FUNCTION__ , __LINE__, pthread_self());
117     //todo: handle version
118     IServerProxy *serverProxy = NULL;
119     proxy->QueryInterface(proxy, SERVER_PROXY_VER, (void *)&serverProxy);
120     if (serverProxy == NULL) {
121     }
122     printf("%s %d %d\n", __FUNCTION__ , __LINE__, pthread_self());
123     // Lock the multi-write
124     int index = VECTOR_FindByKey(&endpoint->routers, proxy);
125     if (index != INVALID_INDEX) {
126         serverProxy->Release((IUnknown *)serverProxy);
127     }
128     printf("%s %d %d\n", __FUNCTION__ , __LINE__, pthread_self());
129     Router *router = SAMGR_Malloc(sizeof(Router));
130     if (router == NULL) {
131         HILOG_ERROR(HILOG_MODULE_SAMGR, "Memory is not enough! Identity<%d, %d>",
132                     id->serviceId, id->featureId);
133         return EC_NOMEMORY;
134     }
135     printf("%s %d %d\n", __FUNCTION__ , __LINE__, pthread_self());
136     router->saName = *saName;
137     router->identity = *id;
138     router->proxy = serverProxy;
139     router->policy = NULL;
140     router->policyNum = 0;
141     index = VECTOR_Add(&endpoint->routers, router);
142     if (index == INVALID_INDEX) {
143         SAMGR_Free(router);
144         return EC_FAILURE;
145     }
146     printf("%s %d %d\n", __FUNCTION__ , __LINE__, pthread_self());
147     Listen(endpoint, index, saName->service, saName->feature);
148     return index;
149 }
150 
SAMGR_AddSysCap(const Endpoint * endpoint,const char * sysCap,BOOL isReg)151 int32 SAMGR_AddSysCap(const Endpoint *endpoint, const char *sysCap, BOOL isReg)
152 {
153     if (endpoint == NULL) {
154         return EC_INVALID;
155     }
156     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_AddSysCap begin");
157     IpcIo req;
158     uint8 data[MAX_DATA_LEN];
159     IpcIoInit(&req, data, MAX_DATA_LEN, 0);
160     WriteUint32(&req, RES_SYSCAP);
161     WriteUint32(&req, OP_PUT);
162     WriteBool(&req, sysCap);
163     WriteBool(&req, isReg);
164 
165     IpcIo reply;
166     void *replyBuf = NULL;
167     SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
168     MessageOption option;
169     MessageOptionInit(&option);
170     int ret = SendRequest(samgr, INVALID_INDEX, &req, &reply,
171                           option, (uintptr_t *)&replyBuf);
172     ret = -ret;
173     int32_t ipcRet = ret;
174     if (ret == EC_SUCCESS) {
175         ReadInt32(&reply, &ipcRet);
176     }
177 
178     if (replyBuf != NULL) {
179         FreeBuffer(replyBuf);
180     }
181     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_AddSysCap ret = %d", ipcRet);
182 
183     return ipcRet;
184 }
185 
SAMGR_GetSysCap(const Endpoint * endpoint,const char * sysCap,BOOL * isReg)186 int32 SAMGR_GetSysCap(const Endpoint *endpoint, const char *sysCap, BOOL *isReg)
187 {
188     if (endpoint == NULL) {
189         return EC_INVALID;
190     }
191     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSysCap begin");
192     IpcIo req;
193     uint8 data[MAX_DATA_LEN];
194     IpcIoInit(&req, data, MAX_DATA_LEN, 0);
195     WriteUint32(&req, RES_SYSCAP);
196     WriteUint32(&req, OP_GET);
197     WriteBool(&req, sysCap);
198 
199     IpcIo reply;
200     void *replyBuf = NULL;
201     SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
202     MessageOption option;
203     MessageOptionInit(&option);
204     int ret = SendRequest(samgr, INVALID_INDEX, &req, &reply,
205                           option, (uintptr_t *)&replyBuf);
206     ret = -ret;
207     *isReg = FALSE;
208     int32_t ipcRet = ret;
209     if (ret == EC_SUCCESS) {
210         (void)ReadInt32(&reply, &ipcRet);
211     }
212     if (ipcRet == EC_SUCCESS) {
213         (void)ReadBool(&reply, (bool *)isReg);
214     }
215     if (replyBuf != NULL) {
216         FreeBuffer(replyBuf);
217     }
218     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSysCap ret = %d", ipcRet);
219     return ipcRet;
220 }
221 
SendGetAllSysCapsRequest(const Endpoint * endpoint,uint32 startIdx,IpcIo * reply,void ** replyBuf)222 static int SendGetAllSysCapsRequest(const Endpoint *endpoint, uint32 startIdx, IpcIo *reply, void **replyBuf)
223 {
224     IpcIo req;
225     uint8 data[MAX_DATA_LEN];
226     IpcIoInit(&req, data, MAX_DATA_LEN, 0);
227     WriteUint32(&req, RES_SYSCAP);
228     WriteUint32(&req, OP_ALL);
229     WriteUint32(&req, startIdx);
230     SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
231     MessageOption option;
232     MessageOptionInit(&option);
233     int ret = SendRequest(samgr, INVALID_INDEX, &req, reply,
234                           option, (uintptr_t *)replyBuf);
235     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SendGetAllSysCapsRequest startIdx:%d, ret:%d!", startIdx, ret);
236     return -ret;
237 }
238 
ParseGetAllSysCapsReply(IpcIo * reply,char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],int32 * sysCapNum,BOOL * isEnd,uint32 * nextRequestIdx)239 static int32 ParseGetAllSysCapsReply(IpcIo *reply, char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],
240                                      int32 *sysCapNum, BOOL *isEnd, uint32 *nextRequestIdx)
241 {
242     int32_t ret;
243     if (ReadInt32(reply, &ret)) {
244         if (ret != EC_SUCCESS) {
245             *isEnd = TRUE;
246             return ret;
247         }
248     } else {
249         *isEnd = TRUE;
250         return EC_INVALID;
251     }
252 
253     (void)ReadBool(reply, (bool *)isEnd);
254     (void)ReadUint32(reply, nextRequestIdx);
255     uint32 size;
256     (void)ReadUint32(reply, &size);
257     size = ((size > MAX_SYSCAP_NUM) ? MAX_SYSCAP_NUM : size);
258     int cnt = *sysCapNum;
259     for (uint32 i = 0; i < size; i++) {
260         uint32 len = 0;
261         char *sysCap = (char *)ReadString(reply, (size_t *)&len);
262         if (sysCap == NULL || len == 0) {
263             continue;
264         }
265         if (strcpy_s(sysCaps[cnt], sizeof(sysCaps[cnt]), sysCap) != EC_SUCCESS) {
266             continue;
267         }
268         cnt++;
269     }
270     *sysCapNum = cnt;
271 
272     return ret;
273 }
274 
SAMGR_GetSystemCapabilities(const Endpoint * endpoint,char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],int32 * sysCapNum)275 int32 SAMGR_GetSystemCapabilities(const Endpoint *endpoint,
276                                   char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum)
277 {
278     if (sysCapNum == NULL) {
279         return EC_INVALID;
280     }
281     *sysCapNum = 0;
282     if (endpoint == NULL) {
283         return EC_INVALID;
284     }
285     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities begin");
286     IpcIo reply;
287     void *replyBuf = NULL;
288     uint32 startIdx = 0;
289     BOOL isEnd = TRUE;
290     int ret;
291     do {
292         ret = SendGetAllSysCapsRequest(endpoint, startIdx, &reply, &replyBuf);
293         if (ret == EC_SUCCESS) {
294             ret = ParseGetAllSysCapsReply(&reply, sysCaps, sysCapNum, &isEnd, &startIdx);
295         }
296         if (replyBuf != NULL) {
297             FreeBuffer(replyBuf);
298         }
299     } while (isEnd == FALSE && ret == EC_SUCCESS);
300     HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSystemCapabilities ret = %d", ret);
301     return ret;
302 }
303 
SAMGR_ProcPolicy(const Endpoint * endpoint,const SaName * saName,int token)304 int SAMGR_ProcPolicy(const Endpoint *endpoint, const SaName *saName, int token)
305 {
306     if (endpoint == NULL || saName == NULL || token == INVALID_INDEX) {
307         return EC_INVALID;
308     }
309     // retry until success or 20 seconds.
310     int ret = EC_INVALID;
311     uint8 retry = 0;
312     SvcIdentity saInfo = {INVALID_INDEX, token, INVALID_INDEX};
313     while (retry < MAX_REGISTER_RETRY_TIMES) {
314         ++retry;
315         PolicyTrans *policy = NULL;
316         uint32 policyNum = 0;
317         ret = RegisterIdentity(saName,  &saInfo, &policy, &policyNum);
318         if (ret != EC_SUCCESS || policy == NULL) {
319             SAMGR_Free(policy);
320             continue;
321         }
322         HILOG_INFO(HILOG_MODULE_SAMGR, "Register server sa<%s, %s> id<%lu, %u> retry:%d ret:%d!",
323                    saName->service, saName->feature, saInfo.handle, saInfo.token, retry, ret);
324         ret = AddPolicyToRouter(endpoint, &saInfo, policy, policyNum);
325         SAMGR_Free(policy);
326         if (ret == EC_SUCCESS) {
327             break;
328         }
329         sleep(REGISTER_RETRY_INTERVAL);
330     }
331     return ret;
332 }
333 
Listen(Endpoint * endpoint,int index,const char * service,const char * feature)334 static void Listen(Endpoint *endpoint, int index, const char *service, const char *feature)
335 {
336     endpoint->registerEP(&endpoint->identity, index, service, feature);
337 }
338 
AddPolicyToRouter(const Endpoint * endpoint,const SvcIdentity * saInfo,const PolicyTrans * policy,uint32 policyNum)339 static int AddPolicyToRouter(const Endpoint *endpoint, const SvcIdentity *saInfo,
340                              const PolicyTrans *policy, uint32 policyNum)
341 {
342     if (endpoint == NULL || saInfo == NULL || policy == NULL) {
343         return EC_INVALID;
344     }
345 
346     Router *router = VECTOR_At((Vector *)&endpoint->routers, saInfo->token);
347     if (router == NULL) {
348         HILOG_ERROR(HILOG_MODULE_SAMGR, "Router <%s, %u> is NULL", endpoint->name, saInfo->token);
349         return EC_INVALID;
350     }
351 
352     if (router->policy != NULL) {
353         return EC_SUCCESS;
354     }
355     router->policyNum = policyNum;
356     if (policyNum == 0) {
357         return EC_INVALID;
358     }
359     router->policy = (PolicyTrans *)SAMGR_Malloc(sizeof(PolicyTrans) * policyNum);
360     if (router->policy == NULL) {
361         return EC_NOMEMORY;
362     }
363     if (memcpy_s(router->policy, sizeof(PolicyTrans) * policyNum, policy,
364                  sizeof(PolicyTrans) * policyNum) != EOK) {
365         SAMGR_Free(router->policy);
366         router->policy = NULL;
367         HILOG_ERROR(HILOG_MODULE_SAMGR, "Add Policy <%s, %s, %s> Failed!",
368                     endpoint->name, router->saName.service, router->saName.feature);
369         return EC_FAILURE;
370     }
371     HILOG_DEBUG(HILOG_MODULE_SAMGR, "Add Policy <%s, %s, %s> Success",
372                 endpoint->name, router->saName.service, router->saName.feature);
373     return EC_SUCCESS;
374 }
375 
Dispatch(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)376 static int Dispatch(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
377 {
378     extern RemoteRegister g_remoteRegister;
379     Endpoint *endpoint = g_remoteRegister.endpoint;
380     uintptr_t saId = 0;
381     ReadInt32(data, &saId);
382     SaNode *saNode = GetSaNodeBySaId(saId);
383     if (saNode == NULL) {
384         HILOG_WARN(HILOG_MODULE_SAMGR, "get sa node by sa id %d is NULL", saId);
385         goto ERROR;
386     }
387     if (TB_CheckMessage(&endpoint->bucket) == BUCKET_BUSY) {
388         HILOG_WARN(HILOG_MODULE_SAMGR, "Flow Control <%u> is NULL", saNode->token);
389         goto ERROR;
390     }
391 
392     Router *router = VECTOR_At(&endpoint->routers, saNode->token);
393     if (router == NULL) {
394         HILOG_ERROR(HILOG_MODULE_SAMGR, "Router <%s, %u> is NULL", endpoint->name, saNode->token);
395         goto ERROR;
396     }
397     Response resp = {0};
398     resp.data = endpoint;
399     Request request = {0};
400     request.msgId = saNode->token;
401     request.data = data;
402     resp.reply = reply;
403     request.msgValue = code;
404     uint32 *ref = NULL;
405     int ret = SAMGR_SendSharedDirectRequest(&router->identity, &request, &resp, &ref, HandleIpc);
406     if (ret != EC_SUCCESS) {
407         HILOG_ERROR(HILOG_MODULE_SAMGR, "Router[%u] Service<%d, %d> is busy",
408                     saNode->token, router->identity.serviceId, router->identity.featureId);
409         goto ERROR;
410     }
411 
412     return EC_SUCCESS;
413 ERROR:
414     return EC_INVALID;
415 }
416 
HandleIpc(const Request * request,const Response * response)417 static void HandleIpc(const Request *request, const Response *response)
418 {
419     Endpoint *endpoint = (Endpoint *)response->data;
420     Router *router = VECTOR_At(&endpoint->routers, request->msgId);
421 
422     router->proxy->Invoke(router->proxy, request->msgValue, NULL, request->data, response->reply);
423 }
424 
CompareIServerProxy(const IServerProxy * proxy1,const IServerProxy * proxy2)425 static int CompareIServerProxy(const IServerProxy *proxy1, const IServerProxy *proxy2)
426 {
427     if (proxy1 == proxy2) {
428         return 0;
429     }
430     return (proxy1 > proxy2) ? 1 : -1;
431 }
432 
GetIServerProxy(const Router * router)433 static IServerProxy *GetIServerProxy(const Router *router)
434 {
435     if (router == NULL) {
436         return NULL;
437     }
438     return router->proxy;
439 }
440 
RegisterIdentity(const SaName * saName,SvcIdentity * saInfo,PolicyTrans ** policy,uint32 * policyNum)441 static int RegisterIdentity(const SaName *saName, SvcIdentity *saInfo,
442                             PolicyTrans **policy, uint32 *policyNum)
443 {
444     IpcIo req;
445     uint8 data[MAX_DATA_LEN];
446     IpcIoInit(&req, data, MAX_DATA_LEN, 0);
447     WriteUint32(&req, RES_FEATURE);
448     WriteUint32(&req, OP_PUT);
449     WriteBool(&req, saName->service);
450     WriteBool(&req, saName->feature == NULL);
451     if (saName->feature != NULL) {
452         WriteBool(&req, saName->feature);
453     }
454     WriteUint32(&req, saInfo->token);
455     IpcIo reply;
456     void *replyBuf = NULL;
457     SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
458     MessageOption option;
459     MessageOptionInit(&option);
460     int ret = SendRequest(samgr, INVALID_INDEX, &req, &reply, option,
461                           (uintptr_t *)&replyBuf);
462     ret = -ret;
463     int32_t ipcRet = EC_FAILURE;
464     if (ret == EC_SUCCESS) {
465         ret = ReadInt32(&reply, &ipcRet);
466     }
467     if (ipcRet == EC_SUCCESS) {
468         SvcIdentity target;
469         (void)ReadRemoteObject(&reply, &target);
470         GetRemotePolicy(&reply, policy, policyNum);
471     }
472     if (replyBuf != NULL) {
473         FreeBuffer(replyBuf);
474     }
475     return ret;
476 }
477 
RegisterRemoteFeatures(Endpoint * endpoint)478 static int RegisterRemoteFeatures(Endpoint *endpoint)
479 {
480     int nums = 0;
481     int size = VECTOR_Size(&endpoint->routers);
482     int i;
483     SvcIdentity identity;
484     for (i = 0; i < size; ++i) {
485         Router *router = VECTOR_At(&endpoint->routers, i);
486         if (router == NULL) {
487             continue;
488         }
489 
490         identity.handle = endpoint->identity.handle;
491         identity.token = i;
492         int ret = RegisterIdentity(&(router->saName), &identity, &(router->policy),
493                                    &(router->policyNum));
494         if (ret == EC_SUCCESS) {
495             ++nums;
496         }
497         HILOG_DEBUG(HILOG_MODULE_SAMGR, "RegisterRemoteFeatures<%s, %s> ret:%d",
498                     router->saName.service, router->saName.feature,  ret);
499     }
500     return VECTOR_Num(&endpoint->routers) - nums;
501 }
502 
RegisterRemoteEndpoint(SvcIdentity * identity,int token,const char * service,const char * feature)503 static int RegisterRemoteEndpoint(SvcIdentity *identity, int token, const char *service, const char *feature)
504 {
505     IpcObjectStub *objectStubOne = (IpcObjectStub *)calloc(1, sizeof(IpcObjectStub));
506     if (objectStubOne == NULL) {
507         return -1;
508     }
509     objectStubOne->func = Dispatch;
510     objectStubOne->isRemote = true;
511     // handle is used by rpc, should be bigger than 0
512     identity->handle = token + 1;
513     identity->cookie = objectStubOne;
514     // token is used by router index, should be itself, and save in SaNode
515     identity->token = token;
516     extern int AddEndpoint(SvcIdentity identity, const char *service, const char *feature);
517     AddEndpoint(*identity, service, feature);
518     return EC_SUCCESS;
519 }
520 
OnSamgrServerExit(void * ipcMsg,IpcIo * data,void * argv)521 static int OnSamgrServerExit(void *ipcMsg, IpcIo *data, void *argv)
522 {
523     (void)data;
524     HILOG_ERROR(HILOG_MODULE_SAMGR, "Disconnect to samgr server!");
525     Endpoint *endpoint = (Endpoint *)argv;
526     if (endpoint == NULL || endpoint->registerEP == NULL) {
527         return EC_FAILURE;
528     }
529     if (ipcMsg != NULL) {
530         FreeBuffer(ipcMsg);
531     }
532     int size = VECTOR_Size(&endpoint->routers);
533     int i;
534     for (i = 0; i < size; i++) {
535         Router *router = VECTOR_At(&endpoint->routers, i);
536         if (router == NULL) {
537             continue;
538         }
539         SAMGR_Free(router->policy);
540         router->policy = NULL;
541         router->policyNum = 0;
542     }
543 
544     SvcIdentity old = endpoint->identity;
545     while (endpoint->registerEP(&endpoint->identity, 0, "", "") != EC_SUCCESS) {
546         HILOG_ERROR(HILOG_MODULE_SAMGR, "Reconnect to samgr server failed!");
547         usleep(RETRY_INTERVAL);
548     }
549     SvcIdentity new = endpoint->identity;
550     if (old.handle != new.handle || old.cookie != new.cookie || old.token != new.token) {
551         HILOG_ERROR(HILOG_MODULE_SAMGR, "Samgr server identity error!");
552         exit(-1);
553     }
554 
555     SvcIdentity identity = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
556     (void)RemoveDeathRecipient(identity, endpoint->deadId);
557     (void)AddDeathRecipient(identity, OnSamgrServerExit, endpoint, &endpoint->deadId);
558     int remain = RegisterRemoteFeatures(endpoint);
559     HILOG_INFO(HILOG_MODULE_SAMGR, "Reconnect and register finished! remain<%d> iunknown!", remain);
560     return EC_SUCCESS;
561 }
562 
GetRemotePolicy(IpcIo * reply,PolicyTrans ** policy,uint32 * policyNum)563 static void GetRemotePolicy(IpcIo *reply, PolicyTrans **policy, uint32 *policyNum)
564 {
565     if (reply == NULL) {
566         return;
567     }
568     uint32 i;
569     uint32 j;
570     ReadUint32(reply, policyNum);
571     if (*policyNum > MAX_POLICY_NUM) {
572         *policyNum = MAX_POLICY_NUM;
573     }
574     SAMGR_Free(*policy);
575     if (*policyNum == 0) {
576         *policy = NULL;
577         return;
578     }
579     *policy = (PolicyTrans *)SAMGR_Malloc(sizeof(PolicyTrans) * (*policyNum));
580     if (*policy == NULL) {
581         return;
582     }
583     for (i = 0; i < *policyNum; i++) {
584         if (ReadInt32(reply, &(*policy)[i].type)) {
585             switch ((*policy)[i].type) {
586                 case RANGE:
587                     ReadInt32(reply, &((*policy)[i].uidMin));
588                     ReadInt32(reply, &((*policy)[i].uidMax));
589                     break;
590                 case FIXED:
591                     for (j = 0; j < UID_SIZE; j++) {
592                         ReadInt32(reply, &((*policy)[i].fixedUid[j]));
593                     }
594                     break;
595                 case BUNDLENAME:
596                     ReadInt32(reply, &((*policy)[i].fixedUid[0]));
597                     break;
598                 default:
599                     break;
600             }
601         }
602     }
603 }
604 
JudgePolicy(uid_t callingUid,const PolicyTrans * policy,uint32 policyNum)605 static boolean JudgePolicy(uid_t callingUid, const PolicyTrans *policy, uint32 policyNum)
606 {
607     if (policy == NULL) {
608         HILOG_ERROR(HILOG_MODULE_SAMGR, "Policy is NULL! Num is %u", policyNum);
609         return FALSE;
610     }
611 
612     uint32 i;
613     for (i = 0; i < policyNum; i++) {
614         if (policy[i].type == RANGE && callingUid >= policy[i].uidMin && callingUid <= policy[i].uidMax) {
615             return TRUE;
616         }
617         if (policy[i].type == FIXED && SearchFixedPolicy(callingUid, policy[i])) {
618             return TRUE;
619         }
620     }
621     return FALSE;
622 }
623 
SearchFixedPolicy(uid_t callingUid,PolicyTrans policy)624 static boolean SearchFixedPolicy(uid_t callingUid, PolicyTrans policy)
625 {
626     int i;
627     for (i = 0; i < UID_SIZE; i++) {
628         if (callingUid == policy.fixedUid[i]) {
629             return TRUE;
630         }
631     }
632     return FALSE;
633 }
634