1 /*
2  * Copyright (c) 2021-2024 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 "event_server.h"
17 
18 #include <fstream>
19 #include <memory>
20 #include <string>
21 #include <vector>
22 
23 #include <fcntl.h>
24 #include <sys/epoll.h>
25 #include <sys/socket.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <sys/un.h>
29 #include <unistd.h>
30 
31 #include <securec.h>
32 
33 #include "base/raw_data_base_def.h"
34 #include "decoded/decoded_event.h"
35 #include "device_node.h"
36 #include "init_socket.h"
37 #include "hiview_logger.h"
38 #include "socket_util.h"
39 
40 #define SOCKET_FILE_DIR "/dev/unix/socket/hisysevent"
41 
42 namespace OHOS {
43 namespace HiviewDFX {
44 DEFINE_LOG_TAG("HiView-EventServer");
45 namespace {
46 constexpr int BUFFER_SIZE = 384 * 1024;
47 #ifndef KERNEL_DEVICE_BUFFER
48 constexpr int EVENT_READ_BUFFER = 2048;
49 #else
50 constexpr int EVENT_READ_BUFFER = KERNEL_DEVICE_BUFFER;
51 #endif
52 
53 struct Header {
54     unsigned short len;
55     unsigned short headerSize;
56     char msg[0];
57 };
58 
InitSocketBuf(int socketId,int optName)59 void InitSocketBuf(int socketId, int optName)
60 {
61     int bufferSizeOld = 0;
62     socklen_t sizeOfInt = static_cast<socklen_t>(sizeof(int));
63     if (getsockopt(socketId, SOL_SOCKET, optName, static_cast<void *>(&bufferSizeOld), &sizeOfInt) < 0) {
64         HIVIEW_LOGE("get socket buffer error=%{public}d, msg=%{public}s", errno, strerror(errno));
65     }
66 
67     int bufferSizeSet = BUFFER_SIZE;
68     if (setsockopt(socketId, SOL_SOCKET, optName, static_cast<void *>(&bufferSizeSet), sizeof(int)) < 0) {
69         HIVIEW_LOGE("set socket buffer error=%{public}d, msg=%{public}s", errno, strerror(errno));
70     }
71 
72     int bufferSizeNew = 0;
73     sizeOfInt = static_cast<socklen_t>(sizeof(int));
74     if (getsockopt(socketId, SOL_SOCKET, optName, static_cast<void *>(&bufferSizeNew), &sizeOfInt) < 0) {
75         HIVIEW_LOGE("get new socket buffer error=%{public}d, msg=%{public}s", errno, strerror(errno));
76     }
77     HIVIEW_LOGI("reset buffer size old=%{public}d, new=%{public}d", bufferSizeOld, bufferSizeNew);
78 }
79 
InitRecvBuffer(int socketId)80 void InitRecvBuffer(int socketId)
81 {
82     InitSocketBuf(socketId, SO_RCVBUF);
83 }
84 
ConverRawData(char * source)85 std::shared_ptr<EventRaw::RawData> ConverRawData(char* source)
86 {
87     if (source == nullptr) {
88         HIVIEW_LOGE("invalid source.");
89         return nullptr;
90     }
91     uint32_t sourceLen = *(reinterpret_cast<uint32_t*>(source));
92     uint32_t desLen = sourceLen + sizeof(uint8_t);
93     uint8_t* des = reinterpret_cast<uint8_t*>(malloc(desLen));
94     if (des == nullptr) {
95         HIVIEW_LOGE("malloc failed.");
96         return nullptr;
97     }
98     uint32_t sourceHeaderLen = sizeof(int32_t) + sizeof(EventRaw::HiSysEventHeader) - sizeof(uint8_t);
99     if (memcpy_s(des, desLen, source, sourceHeaderLen) != EOK) {
100         HIVIEW_LOGE("copy failed.");
101         free(des);
102         return nullptr;
103     }
104     *(reinterpret_cast<uint8_t*>(des + sourceHeaderLen)) = 0; // init header.log flag
105     uint32_t desPos = sourceHeaderLen + sizeof(uint8_t);
106     if (memcpy_s(des + desPos, desLen - desPos, source + sourceHeaderLen, sourceLen - sourceHeaderLen) != EOK) {
107         HIVIEW_LOGE("copy failed.");
108         free(des);
109         return nullptr;
110     }
111     *(reinterpret_cast<int32_t*>(des)) = desLen;
112     auto rawData = std::make_shared<EventRaw::RawData>(des, desLen);
113     free(des);
114     return rawData;
115 }
116 
InitMsgh(char * buffer,int bufferLen,std::array<char,CMSG_SPACE (sizeof (struct ucred))> & control,struct msghdr & msgh,struct iovec & iov)117 void InitMsgh(char* buffer, int bufferLen, std::array<char, CMSG_SPACE(sizeof(struct ucred))>& control,
118     struct msghdr& msgh, struct iovec& iov)
119 {
120     iov.iov_base = buffer;
121     iov.iov_len = static_cast<uint32_t>(bufferLen);
122     msgh.msg_iov = &iov;
123     msgh.msg_iovlen = 1; // 1 is length of io vector
124 
125     msgh.msg_control = control.data();
126     msgh.msg_controllen = control.size();
127 
128     msgh.msg_name = nullptr;
129     msgh.msg_namelen = 0;
130     msgh.msg_flags = 0;
131 }
132 
ReadPidFromMsgh(struct msghdr & msgh)133 pid_t ReadPidFromMsgh(struct msghdr& msgh)
134 {
135     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msgh);
136     if (cmsg == nullptr) {
137         return UN_INIT_INT_TYPE_VAL;
138     }
139     struct ucred* uCredRecv = reinterpret_cast<struct ucred*>(CMSG_DATA(cmsg));
140     if (uCredRecv == nullptr) {
141         return UN_INIT_INT_TYPE_VAL;
142     }
143     return uCredRecv->pid;
144 }
145 }
146 
InitSocket(int & socketId)147 void SocketDevice::InitSocket(int &socketId)
148 {
149     struct sockaddr_un serverAddr;
150     serverAddr.sun_family = AF_UNIX;
151     if (strcpy_s(serverAddr.sun_path, sizeof(serverAddr.sun_path), SOCKET_FILE_DIR) != EOK) {
152         socketId = -1;
153         HIVIEW_LOGE("copy hisysevent dev path failed, error=%{public}d, msg=%{public}s", errno, strerror(errno));
154         return;
155     }
156     serverAddr.sun_path[sizeof(serverAddr.sun_path) - 1] = '\0';
157     socketId = TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
158     if (socketId < 0) {
159         HIVIEW_LOGE("create hisysevent socket failed, error=%{public}d, msg=%{public}s", errno, strerror(errno));
160         return;
161     }
162     InitRecvBuffer(socketId_);
163     unlink(serverAddr.sun_path);
164     if (TEMP_FAILURE_RETRY(bind(socketId, reinterpret_cast<sockaddr*>(&serverAddr), sizeof(serverAddr))) < 0) {
165         close(socketId);
166         socketId = -1;
167         HIVIEW_LOGE("bind hisysevent socket failed, error=%{public}d, msg=%{public}s", errno, strerror(errno));
168         return;
169     }
170 }
171 
Open()172 int SocketDevice::Open()
173 {
174     socketId_ = GetControlSocket("hisysevent");
175     if (socketId_ < 0) {
176         HIVIEW_LOGI("create hisysevent socket");
177         InitSocket(socketId_);
178     } else {
179         InitRecvBuffer(socketId_);
180         HIVIEW_LOGI("use hisysevent exist socket");
181     }
182 
183     if (socketId_ < 0) {
184         HIVIEW_LOGE("hisysevent create socket failed");
185         return -1;
186     }
187     return socketId_;
188 }
189 
Close()190 int SocketDevice::Close()
191 {
192     if (socketId_ > 0) {
193         close(socketId_);
194         socketId_ = -1;
195     }
196     return 0;
197 }
198 
GetEvents()199 uint32_t SocketDevice::GetEvents()
200 {
201     return EPOLLIN | EPOLLET;
202 }
203 
GetName()204 std::string SocketDevice::GetName()
205 {
206     return "SysEventSocket";
207 }
208 
IsValidMsg(char * msg,int32_t len)209 bool SocketDevice::IsValidMsg(char* msg, int32_t len)
210 {
211     if (len < static_cast<int32_t>(EventRaw::GetValidDataMinimumByteCount())) {
212         HIVIEW_LOGD("the data length=%{public}d is invalid", len);
213         return false;
214     }
215     int32_t dataByteCnt = *(reinterpret_cast<int32_t*>(msg));
216     if (dataByteCnt != len) {
217         HIVIEW_LOGW("the data byte count=%{public}d are not equal to read length %{public}d", dataByteCnt, len);
218         return false;
219     }
220     int32_t pid = *(reinterpret_cast<int32_t*>(msg + sizeof(int32_t) + EventRaw::POS_OF_PID_IN_HEADER));
221     if (uCredPid_ > 0 && pid != uCredPid_) {
222         HIVIEW_LOGW("failed to verify the consistensy of process id: [%{public}" PRId32
223             ", %{public}" PRId32 "]", pid, uCredPid_);
224         return false;
225     }
226     msg[len] = '\0';
227     return true;
228 }
229 
SetUCredPid(const pid_t pid)230 void SocketDevice::SetUCredPid(const pid_t pid)
231 {
232     uCredPid_ = pid;
233 }
234 
ReceiveMsg(std::vector<std::shared_ptr<EventReceiver>> & receivers)235 int SocketDevice::ReceiveMsg(std::vector<std::shared_ptr<EventReceiver>> &receivers)
236 {
237     char* buffer = new char[BUFFER_SIZE + 1]();
238     std::array<char, CMSG_SPACE(sizeof(struct ucred))> control = {0};
239     struct msghdr msgh = {0};
240     struct iovec iov = {
241         .iov_base = nullptr,
242         .iov_len = 0
243     };
244     InitMsgh(buffer, BUFFER_SIZE, control, msgh, iov);
245     while (true) {
246         int ret = recvmsg(socketId_, &msgh, 0);
247         if (ret <= 0) {
248             HIVIEW_LOGD("failed to recv msg from socket");
249             break;
250         }
251         pid_t uCredPid = ReadPidFromMsgh(msgh);
252         SetUCredPid(uCredPid);
253         if (!IsValidMsg(buffer, ret)) {
254             break;
255         }
256         for (auto receiver = receivers.begin(); receiver != receivers.end(); receiver++) {
257             (*receiver)->HandlerEvent(ConverRawData(buffer));
258         }
259     }
260     delete[] buffer;
261     return 0;
262 }
263 
Close()264 int BBoxDevice::Close()
265 {
266     if (fd_ > 0) {
267         close(fd_);
268         fd_ = -1;
269     }
270     return 0;
271 }
272 
Open()273 int BBoxDevice::Open()
274 {
275     fd_ = open("/dev/sysevent", O_RDONLY | O_NONBLOCK, 0);
276     if (fd_ < 0) {
277         fd_ = open("/dev/bbox", O_RDONLY | O_NONBLOCK, 0);
278     } else {
279         hasBbox_ = true;
280     }
281 
282     if (fd_ < 0) {
283         HIVIEW_LOGE("open bbox failed, error=%{public}d, msg=%{public}s", errno, strerror(errno));
284         return -1;
285     }
286     return fd_;
287 }
288 
GetEvents()289 uint32_t BBoxDevice::GetEvents()
290 {
291     return EPOLLIN;
292 }
293 
GetName()294 std::string BBoxDevice::GetName()
295 {
296     return "BBox";
297 }
298 
IsValidMsg(char * msg,int32_t len)299 bool BBoxDevice::IsValidMsg(char* msg, int32_t len)
300 {
301     if (len < static_cast<int32_t>(EventRaw::GetValidDataMinimumByteCount())) {
302         HIVIEW_LOGW("the data length=%{public}d is invalid", len);
303         return false;
304     }
305     int32_t dataByteCnt = *(reinterpret_cast<int32_t*>(msg));
306     if ((hasBbox_ && dataByteCnt != len) ||
307         (!hasBbox_ && dataByteCnt != (len - sizeof(struct Header) - 1))) { // extra bytes in kernel write
308         HIVIEW_LOGW("the data lengths=%{public}d are not equal", len);
309         return false;
310     }
311     msg[EVENT_READ_BUFFER - 1] = '\0';
312     return true;
313 }
314 
ReceiveMsg(std::vector<std::shared_ptr<EventReceiver>> & receivers)315 int BBoxDevice::ReceiveMsg(std::vector<std::shared_ptr<EventReceiver>> &receivers)
316 {
317     char buffer[EVENT_READ_BUFFER];
318     (void)memset_s(buffer, sizeof(buffer), 0, sizeof(buffer));
319     int ret = read(fd_, buffer, EVENT_READ_BUFFER);
320     if (!IsValidMsg(buffer, ret)) {
321         return -1;
322     }
323     for (auto receiver = receivers.begin(); receiver != receivers.end(); receiver++) {
324         (*receiver)->HandlerEvent(ConverRawData(buffer));
325     }
326     return 0;
327 }
328 
AddDev(std::shared_ptr<DeviceNode> dev)329 void EventServer::AddDev(std::shared_ptr<DeviceNode> dev)
330 {
331     int fd = dev->Open();
332     if (fd < 0) {
333         HIVIEW_LOGI("open device %{public}s failed", dev->GetName().c_str());
334         return;
335     }
336     devs_[fd] = dev;
337 }
338 
OpenDevs()339 int EventServer::OpenDevs()
340 {
341     AddDev(std::make_shared<SocketDevice>());
342     AddDev(std::make_shared<BBoxDevice>());
343     if (devs_.empty()) {
344         HIVIEW_LOGE("can not open any device");
345         return -1;
346     }
347     HIVIEW_LOGI("has open %{public}zu devices", devs_.size());
348     return 0;
349 }
350 
AddToMonitor(int pollFd,struct epoll_event pollEvents[])351 int EventServer::AddToMonitor(int pollFd, struct epoll_event pollEvents[])
352 {
353     int index = 0;
354     auto it = devs_.begin();
355     while (it != devs_.end()) {
356         HIVIEW_LOGI("add to poll device %{public}s, fd=%{public}d", it->second->GetName().c_str(), it->first);
357         pollEvents[index].data.fd = it->first;
358         pollEvents[index].events = it->second->GetEvents();
359         int ret = epoll_ctl(pollFd, EPOLL_CTL_ADD, it->first, &pollEvents[index]);
360         if (ret < 0) {
361             HIVIEW_LOGE("add to poll fail device %{public}s error=%{public}d, msg=%{public}s",
362                 it->second->GetName().c_str(), errno, strerror(errno));
363             it->second->Close();
364             it = devs_.erase(it);
365         } else {
366             it++;
367         }
368         index++;
369     }
370 
371     if (devs_.empty()) {
372         HIVIEW_LOGE("can not monitor any device");
373         return -1;
374     }
375     HIVIEW_LOGI("monitor devices %{public}zu", devs_.size());
376     return 0;
377 }
378 
Start()379 void EventServer::Start()
380 {
381     HIVIEW_LOGD("start event server");
382     if (OpenDevs() < 0) {
383         return;
384     }
385 
386     int pollFd = epoll_create1(EPOLL_CLOEXEC);
387     if (pollFd < 0) {
388         HIVIEW_LOGE("create poll failed, error=%{public}d, msg=%{public}s", errno, strerror(errno));
389         return;
390     }
391 
392     struct epoll_event pollEvents[devs_.size()];
393     if (AddToMonitor(pollFd, pollEvents) < 0) {
394         return;
395     }
396 
397     HIVIEW_LOGI("go into event loop");
398     isStart_ = true;
399     while (isStart_) {
400         struct epoll_event chkPollEvents[devs_.size()];
401         int eventCount = epoll_wait(pollFd, chkPollEvents, devs_.size(), -1); // -1: Wait indefinitely
402         if (eventCount <= 0) {
403             HIVIEW_LOGD("read event timeout");
404             continue;
405         }
406         for (int ii = 0; ii < eventCount; ii++) {
407             auto it = devs_.find(chkPollEvents[ii].data.fd);
408             it->second->ReceiveMsg(receivers_);
409         }
410     }
411     CloseDevs();
412 }
413 
CloseDevs()414 void EventServer::CloseDevs()
415 {
416     for (auto devItem : devs_) {
417         devItem.second->Close();
418     }
419 }
420 
Stop()421 void EventServer::Stop()
422 {
423     isStart_ = false;
424 }
425 
AddReceiver(std::shared_ptr<EventReceiver> receiver)426 void EventServer::AddReceiver(std::shared_ptr<EventReceiver> receiver)
427 {
428     receivers_.emplace_back(receiver);
429 }
430 } // namespace HiviewDFX
431 } // namespace OHOS
432