• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #include "faultloggerd_client.h"
16 
17 #include <climits>
18 #include <cstdint>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <securec.h>
22 #include <unistd.h>
23 
24 #include <sys/socket.h>
25 #include <sys/syscall.h>
26 #include <sys/un.h>
27 #include <sys/stat.h>
28 
29 #include "dfx_cutil.h"
30 #include "dfx_define.h"
31 #include "dfx_log.h"
32 #include "dfx_util.h"
33 #include "faultloggerd_socket.h"
34 #include "file_util.h"
35 
36 #define FAULTLOGGER_DAEMON_RESP "RESP:COMPLETE"
37 static const int32_t SOCKET_TIMEOUT = 5;
38 
GetSocketConnectionName()39 static std::string GetSocketConnectionName()
40 {
41     char content[NAME_BUF_LEN];
42     GetProcessName(content, sizeof(content));
43     if (std::string(content).find("processdump") != std::string::npos) {
44         return std::string(SERVER_CRASH_SOCKET_NAME);
45     }
46     return std::string(SERVER_SOCKET_NAME);
47 }
48 
RequestFileDescriptor(int32_t type)49 int32_t RequestFileDescriptor(int32_t type)
50 {
51     struct FaultLoggerdRequest request;
52     (void)memset_s(&request, sizeof(request), 0, sizeof(request));
53     request.type = type;
54     request.pid = getpid();
55     request.tid = gettid();
56     request.uid = getuid();
57     request.time = OHOS::HiviewDFX::GetTimeMilliSeconds();
58     return RequestFileDescriptorEx(&request);
59 }
60 
RequestLogFileDescriptor(struct FaultLoggerdRequest * request)61 int32_t RequestLogFileDescriptor(struct FaultLoggerdRequest *request)
62 {
63     request->clientType = (int32_t)FaultLoggerClientType::LOG_FILE_DES_CLIENT;
64     return RequestFileDescriptorEx(request);
65 }
66 
RequestFileDescriptorEx(const struct FaultLoggerdRequest * request)67 int32_t RequestFileDescriptorEx(const struct FaultLoggerdRequest *request)
68 {
69     if (request == nullptr) {
70         DFXLOG_ERROR("nullptr request");
71         return -1;
72     }
73 
74     int sockfd;
75     std::string name = GetSocketConnectionName();
76     if (!StartConnect(sockfd, name.c_str(), SOCKET_TIMEOUT)) {
77         DFXLOG_ERROR("StartConnect failed");
78         return -1;
79     }
80 
81     write(sockfd, request, sizeof(struct FaultLoggerdRequest));
82     int fd = ReadFileDescriptorFromSocket(sockfd);
83     DFXLOG_DEBUG("RequestFileDescriptorEx(%d).\n", fd);
84     close(sockfd);
85     return fd;
86 }
87 
CheckReadResp(int sockfd)88 static bool CheckReadResp(int sockfd)
89 {
90     char ControlBuffer[SOCKET_BUFFER_SIZE] = {0};
91     (void)memset_s(&ControlBuffer, sizeof(ControlBuffer), 0, SOCKET_BUFFER_SIZE);
92 
93     ssize_t nread = read(sockfd, ControlBuffer, sizeof(ControlBuffer) - 1);
94     if (nread != static_cast<ssize_t>(strlen(FAULTLOGGER_DAEMON_RESP))) {
95         DFXLOG_ERROR("nread: %zd.", nread);
96         return false;
97     }
98     return true;
99 }
100 
RequestFileDescriptorByCheck(const struct FaultLoggerdRequest * request)101 static int32_t RequestFileDescriptorByCheck(const struct FaultLoggerdRequest *request)
102 {
103     int32_t fd = -1;
104     if (request == nullptr) {
105         DFXLOG_ERROR("nullptr request");
106         return -1;
107     }
108 
109     int sockfd = -1;
110     do {
111         std::string name = GetSocketConnectionName();
112         if (!StartConnect(sockfd, name.c_str(), SOCKET_TIMEOUT)) {
113             DFXLOG_ERROR("StartConnect failed");
114             break;
115         }
116 
117         write(sockfd, request, sizeof(struct FaultLoggerdRequest));
118 
119         if (!CheckReadResp(sockfd)) {
120             break;
121         }
122 
123         int data = 12345;
124         if (!SendMsgIovToSocket(sockfd, reinterpret_cast<void *>(&data), sizeof(data))) {
125             DFXLOG_ERROR("%s :: Failed to sendmsg.", __func__);
126             break;
127         }
128 
129         fd = ReadFileDescriptorFromSocket(sockfd);
130         DFXLOG_DEBUG("RequestFileDescriptorByCheck(%d).\n", fd);
131     } while (false);
132     close(sockfd);
133     return fd;
134 }
135 
SendUidToServer(int sockfd)136 static int SendUidToServer(int sockfd)
137 {
138     int mRsp = (int)FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT;
139 
140     int data = 12345;
141     if (!SendMsgIovToSocket(sockfd, reinterpret_cast<void *>(&data), sizeof(data))) {
142         DFXLOG_ERROR("%s :: Failed to sendmsg.", __func__);
143         return mRsp;
144     }
145 
146     char recvbuf[SOCKET_BUFFER_SIZE] = {'\0'};
147     ssize_t count = recv(sockfd, recvbuf, sizeof(recvbuf), 0);
148     if (count < 0) {
149         DFXLOG_ERROR("%s :: Failed to recv.", __func__);
150         return mRsp;
151     }
152 
153     mRsp = atoi(recvbuf);
154     return mRsp;
155 }
156 
CheckConnectStatus()157 bool CheckConnectStatus()
158 {
159     int sockfd = -1;
160     std::string name = GetSocketConnectionName();
161     if (StartConnect(sockfd, name.c_str(), -1)) {
162         close(sockfd);
163         return true;
164     }
165     return false;
166 }
167 
SendRequestToServer(const FaultLoggerdRequest & request)168 static int SendRequestToServer(const FaultLoggerdRequest &request)
169 {
170     int sockfd = -1;
171     int resRsp = (int)FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT;
172     do {
173         std::string name = GetSocketConnectionName();
174         if (!StartConnect(sockfd, name.c_str(), -1)) {
175             DFXLOG_ERROR("StartConnect failed.");
176             break;
177         }
178         if (write(sockfd, &request, sizeof(struct FaultLoggerdRequest)) != static_cast<long>(sizeof(request))) {
179             DFXLOG_ERROR("write failed.");
180             break;
181         }
182 
183         if (!CheckReadResp(sockfd)) {
184             break;
185         }
186         resRsp = SendUidToServer(sockfd);
187     } while (false);
188 
189     close(sockfd);
190     DFXLOG_INFO("SendRequestToServer :: resRsp(%d).", resRsp);
191     return resRsp;
192 }
193 
RequestCheckPermission(int32_t pid)194 bool RequestCheckPermission(int32_t pid)
195 {
196     DFXLOG_INFO("RequestCheckPermission :: %d.", pid);
197     if (pid <= 0) {
198         return false;
199     }
200 
201     struct FaultLoggerdRequest request;
202     (void)memset_s(&request, sizeof(request), 0, sizeof(request));
203 
204     request.pid = pid;
205     request.clientType = (int32_t)FaultLoggerClientType::PERMISSION_CLIENT;
206 
207     bool ret = false;
208     if (SendRequestToServer(request) == (int)FaultLoggerCheckPermissionResp::CHECK_PERMISSION_PASS) {
209         ret = true;
210     }
211     return ret;
212 }
213 
RequestSdkDump(int32_t type,int32_t pid,int32_t tid)214 int RequestSdkDump(int32_t type, int32_t pid, int32_t tid)
215 {
216     return RequestSdkDumpJson(type, pid, tid, false);
217 }
218 
RequestSdkDumpJson(int32_t type,int32_t pid,int32_t tid,bool isJson)219 int RequestSdkDumpJson(int32_t type, int32_t pid, int32_t tid, bool isJson)
220 {
221     DFXLOG_INFO("RequestSdkDumpJson :: type(%d), pid(%d), tid(%d).", type, pid, tid);
222     if (pid <= 0 || tid < 0) {
223         return -1;
224     }
225 
226     struct FaultLoggerdRequest request;
227     (void)memset_s(&request, sizeof(request), 0, sizeof(request));
228     request.isJson = isJson;
229     request.sigCode = type;
230     request.pid = pid;
231     request.tid = tid;
232     request.callerPid = getpid();
233     request.callerTid = syscall(SYS_gettid);
234     request.clientType = (int32_t)FaultLoggerClientType::SDK_DUMP_CLIENT;
235     request.time = OHOS::HiviewDFX::GetTimeMilliSeconds();
236 
237     return SendRequestToServer(request);
238 }
239 
RequestPrintTHilog(const char * msg,int length)240 int RequestPrintTHilog(const char *msg, int length)
241 {
242     if (length >= LINE_BUF_SIZE) {
243         return -1;
244     }
245 
246     struct FaultLoggerdRequest request;
247     (void)memset_s(&request, sizeof(request), 0, sizeof(request));
248     request.clientType = (int32_t)FaultLoggerClientType::PRINT_T_HILOG_CLIENT;
249     request.pid = getpid();
250     request.uid = getuid();
251     int sockfd = -1;
252     do {
253         std::string name = GetSocketConnectionName();
254         if (!StartConnect(sockfd, name.c_str(), -1)) {
255             DFXLOG_ERROR("StartConnect failed");
256             break;
257         }
258 
259         if (write(sockfd, &request, sizeof(struct FaultLoggerdRequest)) != static_cast<long>(sizeof(request))) {
260             break;
261         }
262 
263         if (!CheckReadResp(sockfd)) {
264             break;
265         }
266 
267         int nwrite = write(sockfd, msg, strlen(msg));
268         if (nwrite != static_cast<long>(strlen(msg))) {
269             DFXLOG_ERROR("nwrite: %d.", nwrite);
270             break;
271         }
272         close(sockfd);
273         return 0;
274     } while (false);
275     close(sockfd);
276     return -1;
277 }
278 
RequestPipeFd(int32_t pid,int32_t pipeType)279 int32_t RequestPipeFd(int32_t pid, int32_t pipeType)
280 {
281     if (pipeType < static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_READ_BUF) ||
282         pipeType > static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_DELETE)) {
283         DFXLOG_ERROR("%s :: pipeType(%d) failed.", __func__, pipeType);
284         return -1;
285     }
286     struct FaultLoggerdRequest request;
287     (void)memset_s(&request, sizeof(request), 0, sizeof(struct FaultLoggerdRequest));
288 
289     if ((pipeType == static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_JSON_READ_BUF)) ||
290         (pipeType == static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_JSON_READ_RES))) {
291         request.isJson = true;
292     } else {
293         request.isJson = false;
294     }
295     request.pipeType = pipeType;
296     request.pid = pid;
297     request.callerPid = getpid();
298     request.callerTid = syscall(SYS_gettid);
299     request.clientType = (int32_t)FaultLoggerClientType::PIPE_FD_CLIENT;
300     if ((pipeType == static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_READ_BUF)) ||
301         (pipeType == static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_READ_RES)) ||
302         (pipeType == static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_JSON_READ_BUF)) ||
303         (pipeType == static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_JSON_READ_RES))) {
304         return RequestFileDescriptorByCheck(&request);
305     }
306     return RequestFileDescriptorEx(&request);
307 }
308 
RequestDelPipeFd(int32_t pid)309 int32_t RequestDelPipeFd(int32_t pid)
310 {
311     struct FaultLoggerdRequest request;
312     (void)memset_s(&request, sizeof(request), 0, sizeof(struct FaultLoggerdRequest));
313     request.pipeType = FaultLoggerPipeType::PIPE_FD_DELETE;
314     request.pid = pid;
315     request.clientType = (int32_t)FaultLoggerClientType::PIPE_FD_CLIENT;
316 
317     int sockfd;
318     std::string name = GetSocketConnectionName();
319     if (!StartConnect(sockfd, name.c_str(), SOCKET_TIMEOUT)) {
320         DFXLOG_ERROR("StartConnect failed");
321         return -1;
322     }
323 
324     write(sockfd, &request, sizeof(struct FaultLoggerdRequest));
325     close(sockfd);
326     return 0;
327 }
328