• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #include "init_param.h"
16 
17 #include <errno.h>
18 #include <stddef.h>
19 #include <string.h>
20 #include <sys/socket.h>
21 #include <unistd.h>
22 
23 #include "init_log.h"
24 #include "init_utils.h"
25 #include "param_atomic.h"
26 #include "param_manager.h"
27 #include "param_message.h"
28 #include "param_security.h"
29 
30 #define INVALID_SOCKET (-1)
31 static const uint32_t RECV_BUFFER_MAX = 5 * 1024;
32 static ATOMIC_UINT32 g_requestId;
33 static int g_clientFd = INVALID_SOCKET;
34 static pthread_mutex_t g_clientMutex = PTHREAD_MUTEX_INITIALIZER;
35 
ParameterInit(void)36 __attribute__((constructor)) static void ParameterInit(void)
37 {
38     ATOMIC_INIT(&g_requestId, 1);
39     EnableInitLog(INIT_INFO);
40 
41     PARAM_WORKSPACE_OPS ops = {0};
42     ops.updaterMode = 0;
43     ops.logFunc = InitLog;
44 #ifdef PARAM_SUPPORT_SELINUX
45     ops.setfilecon = NULL;
46 #endif
47     InitParamWorkSpace(1, &ops);
48 
49     // modify log level
50     char logLevel[2] = {0}; // 2 is set param "persist.init.debug.loglevel" value length.
51     uint32_t len = sizeof(logLevel);
52     int ret = SystemReadParam(INIT_DEBUG_LEVEL, logLevel, &len);
53     if (ret == 0) {
54         errno = 0;
55         int level = atoi(logLevel);
56         if (errno != 0) {
57             return;
58         }
59         SetInitLogLevel((InitLogLevel)level);
60     }
61 }
62 
ParameterDeinit(void)63 __attribute__((destructor)) static void ParameterDeinit(void)
64 {
65     if (g_clientFd != INVALID_SOCKET) {
66         close(g_clientFd);
67         g_clientFd = INVALID_SOCKET;
68     }
69     pthread_mutex_destroy(&g_clientMutex);
70 }
71 
ProcessRecvMsg(const ParamMessage * recvMsg)72 static int ProcessRecvMsg(const ParamMessage *recvMsg)
73 {
74     PARAM_LOGV("ProcessRecvMsg type: %u msgId: %u name %s", recvMsg->type, recvMsg->id.msgId, recvMsg->key);
75     int result = PARAM_CODE_INVALID_PARAM;
76     switch (recvMsg->type) {
77         case MSG_SET_PARAM:
78         case MSG_SAVE_PARAM:
79             result = ((ParamResponseMessage *)recvMsg)->result;
80             break;
81         case MSG_NOTIFY_PARAM: {
82             uint32_t offset = 0;
83             ParamMsgContent *valueContent = GetNextContent(recvMsg, &offset);
84             PARAM_CHECK(valueContent != NULL, return PARAM_CODE_TIMEOUT, "Invalid msg");
85             result = 0;
86             break;
87         }
88         default:
89             break;
90     }
91     return result;
92 }
93 
ReadMessage(int fd,char * buffer,uint32_t timeout)94 static int ReadMessage(int fd, char *buffer, uint32_t timeout)
95 {
96     int ret = 0;
97     uint32_t diff = 0;
98     struct timespec startTime = {0};
99     (void)clock_gettime(CLOCK_MONOTONIC, &startTime);
100     do {
101         ssize_t recvLen = recv(fd, (char *)buffer, RECV_BUFFER_MAX, 0);
102         if (recvLen <= 0) {
103             PARAM_LOGE("ReadMessage failed! errno %d", errno);
104             struct timespec finishTime = {0};
105             (void)clock_gettime(CLOCK_MONOTONIC, &finishTime);
106             diff = IntervalTime(&finishTime, &startTime);
107             if (diff >= timeout) {
108                 ret = PARAM_CODE_TIMEOUT;
109                 break;
110             }
111             if (errno == EAGAIN || errno == EINTR) {
112                 usleep(10*1000); // 10*1000 wait 10ms
113                 continue;
114             }
115         }
116 
117         if (recvLen > sizeof(ParamMessage)) {
118             PARAM_LOGV("recv message len is %d", recvLen);
119             break;
120         }
121     } while (1);
122 
123     if (ret != 0) {
124         PARAM_LOGE("ReadMessage errno %d diff %u timeout %d ret %d", errno, diff, timeout, ret);
125     }
126     return ret;
127 }
128 
GetClientSocket(int timeout)129 static int GetClientSocket(int timeout)
130 {
131     struct timeval time = {0};
132     time.tv_sec = timeout;
133     time.tv_usec = 0;
134     int clientFd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
135     PARAM_CHECK(clientFd >= 0, return INVALID_SOCKET, "Failed to create socket");
136     int ret = ConnectServer(clientFd, CLIENT_PIPE_NAME);
137     if (ret == 0) {
138         setsockopt(clientFd, SOL_SOCKET, SO_SNDTIMEO, (char *)&time, sizeof(struct timeval));
139         setsockopt(clientFd, SOL_SOCKET, SO_RCVTIMEO, (char *)&time, sizeof(struct timeval));
140     } else {
141         close(clientFd);
142         clientFd = INVALID_SOCKET;
143     }
144     return clientFd;
145 }
146 
StartRequest(int clientFd,ParamMessage * request,int timeout)147 static int StartRequest(int clientFd, ParamMessage *request, int timeout)
148 {
149     errno = 0;
150     ssize_t sendLen = send(clientFd, (char *)request, request->msgSize, 0);
151     if (errno == EINVAL || errno == EACCES) {
152         PARAM_LOGE("send Message failed!");
153         return PARAM_CODE_IPC_ERROR;
154     }
155     PARAM_CHECK(sendLen >= 0, return PARAM_CODE_IPC_ERROR, "Failed to send message err: %d", errno);
156     PARAM_LOGV("sendMessage sendLen fd %d %zd", clientFd, sendLen);
157     if (timeout <= 0) {
158         return 0;
159     }
160     int ret = ReadMessage(clientFd, (char *)request, timeout);
161     if (ret == 0) {
162         ret = ProcessRecvMsg(request);
163     }
164     return ret;
165 }
166 
SystemSetParameter_(const char * name,const char * value,int timeout)167 static int SystemSetParameter_(const char *name, const char *value, int timeout)
168 {
169     PARAM_CHECK(name != NULL && value != NULL, return -1, "Invalid name or value");
170     int ret = CheckParamName(name, 0);
171     PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name);
172     ret = CheckParamValue(NULL, name, value, GetParamValueType(name));
173     PARAM_CHECK(ret == 0, return ret, "Illegal param value %s", value);
174 
175     size_t msgSize = sizeof(ParamMsgContent);
176     msgSize = (msgSize < RECV_BUFFER_MAX) ? RECV_BUFFER_MAX : msgSize;
177 
178     ParamMessage *request = (ParamMessage *)CreateParamMessage(MSG_SET_PARAM, name, msgSize);
179     PARAM_CHECK(request != NULL, return PARAM_CODE_ERROR, "Failed to create Param Message");
180     uint32_t offset = 0;
181     ret = FillParamMsgContent(request, &offset, PARAM_VALUE, value, strlen(value));
182     PARAM_CHECK(ret == 0, free(request);
183         return PARAM_CODE_ERROR, "Failed to fill value");
184     request->msgSize = offset + sizeof(ParamMessage);
185     request->id.msgId = ATOMIC_SYNC_ADD_AND_FETCH(&g_requestId, 1, MEMORY_ORDER_RELAXED);
186 
187     pthread_mutex_lock(&g_clientMutex);
188     int retryCount = 0;
189     while (retryCount < 2) { // max retry 2
190         if (g_clientFd == INVALID_SOCKET) {
191             g_clientFd = GetClientSocket(DEFAULT_PARAM_SET_TIMEOUT);
192         }
193 
194         if (g_clientFd < 0) {
195             ret = PARAM_CODE_FAIL_CONNECT;
196             PARAM_LOGE("connect param server failed!");
197             break;
198         }
199         ret = StartRequest(g_clientFd, request, timeout);
200         if (ret == PARAM_CODE_IPC_ERROR) {
201             close(g_clientFd);
202             g_clientFd = INVALID_SOCKET;
203             retryCount++;
204         } else {
205             break;
206         }
207     }
208     PARAM_LOGI("SystemSetParameter name %s msgid:%d  ret: %d ", name, request->id.msgId, ret);
209     pthread_mutex_unlock(&g_clientMutex);
210     free(request);
211     return ret;
212 }
213 
SystemSetParameter(const char * name,const char * value)214 int SystemSetParameter(const char *name, const char *value)
215 {
216     int ret = SystemSetParameter_(name, value, DEFAULT_PARAM_SET_TIMEOUT);
217     BEGET_CHECK_ONLY_ELOG(ret == 0, "SystemSetParameter failed! name is :%s, the errNum is:%d", name, ret);
218     return ret;
219 }
220 
SystemSetParameterNoWait(const char * name,const char * value)221 int SystemSetParameterNoWait(const char *name, const char *value)
222 {
223     int ret = SystemSetParameter_(name, value, 0);
224     BEGET_CHECK_ONLY_ELOG(ret == 0, "SystemSetParameterNoWait failed! name is:%s, the errNum is:%d", name, ret);
225     return ret;
226 }
227 
SystemSaveParameters(void)228 int SystemSaveParameters(void)
229 {
230     const char *name = "persist.all";
231     size_t msgSize = RECV_BUFFER_MAX;
232     uint32_t offset = 0;
233     ParamMessage *request = (ParamMessage *)CreateParamMessage(MSG_SAVE_PARAM, name, msgSize);
234     PARAM_CHECK(request != NULL, return -1, "SystemSaveParameters failed! name is:%s, the errNum is:-1", name);
235     int ret = FillParamMsgContent(request, &offset, PARAM_VALUE, "*", 1);
236     PARAM_CHECK(ret == 0, free(request);
237         return -1, "SystemSaveParameters failed! the errNum is:-1");
238     int fd = GetClientSocket(DEFAULT_PARAM_WAIT_TIMEOUT);
239     PARAM_CHECK(fd >= 0, return fd, "SystemSaveParameters failed! the errNum is:%d", ret);
240     request->msgSize = offset + sizeof(ParamMessage);
241     request->id.msgId = ATOMIC_SYNC_ADD_AND_FETCH(&g_requestId, 1, MEMORY_ORDER_RELAXED);
242     ret = StartRequest(fd, request, DEFAULT_PARAM_WAIT_TIMEOUT);
243     close(fd);
244     free(request);
245     BEGET_CHECK_ONLY_ELOG(ret == 0, "SystemSaveParameters failed! the errNum is:%d", ret);
246     return ret;
247 }
248 
SystemWaitParameter(const char * name,const char * value,int32_t timeout)249 int SystemWaitParameter(const char *name, const char *value, int32_t timeout)
250 {
251     PARAM_CHECK(name != NULL, return -1, "SystemWaitParameter failed! name is:%s, the errNum is:-1", name);
252     int ret = CheckParamName(name, 0);
253     PARAM_CHECK(ret == 0, return ret, "SystemWaitParameter failed! name is:%s, the errNum is:%d", name, ret);
254     ret = CheckParamPermission(GetParamSecurityLabel(), name, DAC_READ);
255     PARAM_CHECK(ret == 0, return ret, "SystemWaitParameter failed! name is:%s, the errNum is:%d", name, ret);
256     if (timeout <= 0) {
257         timeout = DEFAULT_PARAM_WAIT_TIMEOUT;
258     }
259     uint32_t msgSize = sizeof(ParamMessage) + sizeof(ParamMsgContent) + sizeof(ParamMsgContent) + sizeof(uint32_t);
260     msgSize = (msgSize < RECV_BUFFER_MAX) ? RECV_BUFFER_MAX : msgSize;
261     uint32_t offset = 0;
262     ParamMessage *request = NULL;
263     if (value != NULL && strlen(value) > 0) {
264         msgSize += PARAM_ALIGN(strlen(value) + 1);
265         request = (ParamMessage *)CreateParamMessage(MSG_WAIT_PARAM, name, msgSize);
266         PARAM_CHECK(request != NULL, return -1, "SystemWaitParameter failed! name is:%s, the errNum is:-1", name);
267         ret = FillParamMsgContent(request, &offset, PARAM_VALUE, value, strlen(value));
268     } else {
269         msgSize += PARAM_ALIGN(1);
270         request = (ParamMessage *)CreateParamMessage(MSG_WAIT_PARAM, name, msgSize);
271         PARAM_CHECK(request != NULL, return -1, "SystemWaitParameter failed! name is:%s, the errNum is:-1", name);
272         ret = FillParamMsgContent(request, &offset, PARAM_VALUE, "*", 1);
273     }
274     PARAM_CHECK(ret == 0, free(request);
275         return -1, "SystemWaitParameter failed! name is:%s, the errNum is:-1", name);
276     ParamMsgContent *content = (ParamMsgContent *)(request->data + offset);
277     content->type = PARAM_WAIT_TIMEOUT;
278     content->contentSize = sizeof(uint32_t);
279     *((uint32_t *)(content->content)) = timeout;
280     offset += sizeof(ParamMsgContent) + sizeof(uint32_t);
281 
282     request->msgSize = offset + sizeof(ParamMessage);
283     request->id.waitId = ATOMIC_SYNC_ADD_AND_FETCH(&g_requestId, 1, MEMORY_ORDER_RELAXED);
284 #ifdef STARTUP_INIT_TEST
285     timeout = 1;
286 #endif
287     int fd = GetClientSocket(timeout);
288     PARAM_CHECK(fd >= 0, return fd, "SystemWaitParameter failed! name is:%s, the errNum is:%d", name, ret);
289     ret = StartRequest(fd, request, timeout);
290     close(fd);
291     free(request);
292     PARAM_LOGI("SystemWaitParameter %s value %s result %d ", name, value, ret);
293     BEGET_CHECK_ONLY_ELOG(ret == 0, "SystemWaitParameter failed! name is:%s, the errNum is:%d", name, ret);
294     return ret;
295 }
296 
SystemCheckParamExist(const char * name)297 int SystemCheckParamExist(const char *name)
298 {
299     return SysCheckParamExist(name);
300 }
301 
WatchParamCheck(const char * keyprefix)302 int WatchParamCheck(const char *keyprefix)
303 {
304     PARAM_CHECK(keyprefix != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid keyprefix");
305     int ret = CheckParamName(keyprefix, 0);
306     PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", keyprefix);
307     ret = CheckParamPermission(GetParamSecurityLabel(), keyprefix, DAC_WATCH);
308     PARAM_CHECK(ret == 0, return ret, "Forbid to watcher parameter %s", keyprefix);
309     return 0;
310 }
311 
ResetParamSecurityLabel(void)312 void ResetParamSecurityLabel(void)
313 {
314 #ifdef RESET_CHILD_FOR_VERIFY
315     ParamWorkSpace *paramSpace = GetParamWorkSpace();
316     PARAM_CHECK(paramSpace != NULL, return, "Invalid paramSpace");
317 #if !(defined __LITEOS_A__ || defined __LITEOS_M__)
318     paramSpace->securityLabel.cred.pid = getpid();
319     paramSpace->securityLabel.cred.uid = geteuid();
320     paramSpace->securityLabel.cred.gid = getegid();
321     paramSpace->flags |= WORKSPACE_FLAGS_NEED_ACCESS;
322 #endif
323 #endif
324     PARAM_LOGI("ResetParamSecurityLabel g_clientFd: %d ", g_clientFd);
325     pthread_mutex_lock(&g_clientMutex);
326     if (g_clientFd != INVALID_SOCKET) {
327         close(g_clientFd);
328         g_clientFd = INVALID_SOCKET;
329     }
330     pthread_mutex_unlock(&g_clientMutex);
331 }
332