• 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 <stdbool.h> /* bool */
17 #include <stddef.h> /* NULL */
18 #include <stdlib.h> /* malloc */
19 
20 #include "hilog/log_c.h"
21 #include "../../common/include/pm_ptr_util.h"
22 #include "purgeable_mem_builder_c.h"
23 
24 #undef LOG_TAG
25 #define LOG_TAG "PurgeableMemC: Builder"
26 
27 /* purgeable mem builder */
28 struct PurgMemBuilder {
29     struct PurgMemBuilder *nextBuilder;
30     PurgMemBuilderFunc Build;
31     void *param;
32     const char *name;
33 };
34 
35 /* append a guest builder @newcomer to @head */
36 static void AppendBuilder_(struct PurgMemBuilder *head, struct PurgMemBuilder *newcomer);
37 
PurgMemBuilderCreate(PurgMemBuilderFunc func,void * param,const char * name)38 struct PurgMemBuilder *PurgMemBuilderCreate(PurgMemBuilderFunc func, void *param, const char *name)
39 {
40     IF_NULL_LOG_ACTION(func, "func is NULL", return NULL);
41 
42     struct PurgMemBuilder *builder = NULL;
43     builder = (struct PurgMemBuilder *)malloc(sizeof(struct PurgMemBuilder));
44     if (!builder) {
45         HILOG_ERROR(LOG_CORE, "%{public}s: malloc struct PurgMemBuilder failed", __func__);
46         return NULL;
47     }
48     builder->Build = func;
49     builder->nextBuilder = NULL;
50     builder->param = param;
51     builder->name = name;
52     return builder;
53 }
54 
PurgMemBuilderDestroy(struct PurgMemBuilder * builder)55 bool PurgMemBuilderDestroy(struct PurgMemBuilder *builder)
56 {
57     IF_NULL_LOG_ACTION(builder, "builder is NULL", return true);
58 
59     struct PurgMemBuilder *curr = builder;
60     struct PurgMemBuilder *next = NULL;
61     while (curr) {
62         next = curr->nextBuilder;
63         free(curr);
64         curr = next;
65     }
66     /* set input para NULL to avoid UAF */
67     builder = NULL;
68     return true;
69 }
70 
PurgMemBuilderAppendFunc(struct PurgMemBuilder * builder,PurgMemBuilderFunc func,void * param,const char * name)71 bool PurgMemBuilderAppendFunc(struct PurgMemBuilder *builder, PurgMemBuilderFunc func, void *param,
72                               const char *name)
73 {
74     IF_NULL_LOG_ACTION(builder, "input builder is NULL", return false);
75     IF_NULL_LOG_ACTION(func, "input func is NULL", return false);
76 
77     struct PurgMemBuilder *newcomer = PurgMemBuilderCreate(func, param, name);
78     IF_NULL_LOG_ACTION(newcomer, "create new builder failed", return false);
79 
80     AppendBuilder_(builder, newcomer);
81     return true;
82 }
83 
84 /* build @data content from @builder */
PurgMemBuilderBuildAll(struct PurgMemBuilder * builder,void * data,size_t size)85 bool PurgMemBuilderBuildAll(struct PurgMemBuilder *builder, void *data, size_t size)
86 {
87     if (!(builder->Build)) {
88         HILOG_ERROR(LOG_CORE, "builder has no Build(), %{public}s", builder->name);
89         return true;
90     }
91     if (!(builder->Build(data, size, builder->param))) {
92         HILOG_ERROR(LOG_CORE, "build data failed, name %{public}s", builder->name ?: "NULL");
93         return false;
94     }
95     if (!(builder->nextBuilder)) {
96         return true;
97     }
98     return PurgMemBuilderBuildAll(builder->nextBuilder, data, size);
99 }
100 
PurgMemBuilderAppendBuilder(struct PurgMemBuilder * builder,struct PurgMemBuilder * newcomer)101 bool PurgMemBuilderAppendBuilder(struct PurgMemBuilder *builder, struct PurgMemBuilder *newcomer)
102 {
103     IF_NULL_LOG_ACTION(builder, "input builder is NULL", return false);
104     IF_NULL_LOG_ACTION(newcomer, "input newcomer is NULL", return false);
105 
106     AppendBuilder_(builder, newcomer);
107     return true;
108 }
109 
110 /* append a guest builder @newcomer to @head */
AppendBuilder_(struct PurgMemBuilder * head,struct PurgMemBuilder * newcomer)111 static void AppendBuilder_(struct PurgMemBuilder *head, struct PurgMemBuilder *newcomer)
112 {
113     if (!head->nextBuilder) {
114         head->nextBuilder = newcomer;
115         return;
116     }
117     return AppendBuilder_(head->nextBuilder, newcomer);
118 }
119