• 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_define.h"
30 #include "dfx_log.h"
31 #include "dfx_util.h"
32 #include "faultloggerd_socket.h"
33 #include "file_util.h"
34 
35 #define FAULTLOGGER_DAEMON_RESP "RESP:COMPLETE"
36 static const int32_t SOCKET_TIMEOUT = 5;
37 
GetSocketConnectionName()38 static std::string GetSocketConnectionName()
39 {
40     std::string content;
41     OHOS::HiviewDFX::LoadStringFromFile(PROC_SELF_CMDLINE_PATH, content);
42     if (content.find("processdump") != std::string::npos) {
43         return std::string(SERVER_CRASH_SOCKET_NAME);
44     }
45     return std::string(SERVER_SOCKET_NAME);
46 }
47 
RequestFileDescriptor(int32_t type)48 int32_t RequestFileDescriptor(int32_t type)
49 {
50     struct FaultLoggerdRequest request;
51     (void)memset_s(&request, sizeof(request), 0, sizeof(request));
52     request.type = type;
53     request.pid = getpid();
54     request.tid = gettid();
55     request.uid = getuid();
56     request.time = OHOS::HiviewDFX::GetTimeMilliSeconds();
57     return RequestFileDescriptorEx(&request);
58 }
59 
RequestLogFileDescriptor(struct FaultLoggerdRequest * request)60 int32_t RequestLogFileDescriptor(struct FaultLoggerdRequest *request)
61 {
62     request->clientType = (int32_t)FaultLoggerClientType::LOG_FILE_DES_CLIENT;
63     return RequestFileDescriptorEx(request);
64 }
65 
RequestFileDescriptorEx(const struct FaultLoggerdRequest * request)66 int32_t RequestFileDescriptorEx(const struct FaultLoggerdRequest *request)
67 {
68     if (request == nullptr) {
69         DFXLOG_ERROR("nullptr request");
70         return -1;
71     }
72 
73     int sockfd;
74     std::string name = GetSocketConnectionName();
75     if (!StartConnect(sockfd, name.c_str(), SOCKET_TIMEOUT)) {
76         DFXLOG_ERROR("StartConnect failed");
77         return -1;
78     }
79 
80     write(sockfd, request, sizeof(struct FaultLoggerdRequest));
81     int fd = ReadFileDescriptorFromSocket(sockfd);
82     DFXLOG_DEBUG("RequestFileDescriptorEx(%d).\n", fd);
83     close(sockfd);
84     return fd;
85 }
86 
CheckReadResp(int sockfd)87 static bool CheckReadResp(int sockfd)
88 {
89     char ControlBuffer[SOCKET_BUFFER_SIZE] = {0};
90     (void)memset_s(&ControlBuffer, sizeof(ControlBuffer), 0, SOCKET_BUFFER_SIZE);
91 
92     ssize_t nread = read(sockfd, ControlBuffer, sizeof(ControlBuffer) - 1);
93     if (nread != static_cast<ssize_t>(strlen(FAULTLOGGER_DAEMON_RESP))) {
94         DFXLOG_ERROR("nread: %d.", nread);
95         return false;
96     }
97     return true;
98 }
99 
RequestFileDescriptorByCheck(const struct FaultLoggerdRequest * request)100 static int32_t RequestFileDescriptorByCheck(const struct FaultLoggerdRequest *request)
101 {
102     int32_t fd = -1;
103     if (request == nullptr) {
104         DFXLOG_ERROR("nullptr request");
105         return -1;
106     }
107 
108     int sockfd = -1;
109     do {
110         std::string name = GetSocketConnectionName();
111         if (!StartConnect(sockfd, name.c_str(), SOCKET_TIMEOUT)) {
112             DFXLOG_ERROR("StartConnect failed");
113             break;
114         }
115 
116         write(sockfd, request, sizeof(struct FaultLoggerdRequest));
117 
118         if (!CheckReadResp(sockfd)) {
119             break;
120         }
121 
122         int data = 12345;
123         if (!SendMsgIovToSocket(sockfd, reinterpret_cast<void *>(&data), sizeof(data))) {
124             DFXLOG_ERROR("%s :: Failed to sendmsg.", __func__);
125             break;
126         }
127 
128         fd = ReadFileDescriptorFromSocket(sockfd);
129         DFXLOG_DEBUG("RequestFileDescriptorByCheck(%d).\n", fd);
130     } while (false);
131     close(sockfd);
132     return fd;
133 }
134 
SendUidToServer(int sockfd)135 static int SendUidToServer(int sockfd)
136 {
137     int mRsp = (int)FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT;
138 
139     int data = 12345;
140     if (!SendMsgIovToSocket(sockfd, reinterpret_cast<void *>(&data), sizeof(data))) {
141         DFXLOG_ERROR("%s :: Failed to sendmsg.", __func__);
142         return mRsp;
143     }
144 
145     char recvbuf[SOCKET_BUFFER_SIZE] = {'\0'};
146     ssize_t count = recv(sockfd, recvbuf, sizeof(recvbuf), 0);
147     if (count < 0) {
148         DFXLOG_ERROR("%s :: Failed to recv.", __func__);
149         return mRsp;
150     }
151 
152     mRsp = atoi(recvbuf);
153     return mRsp;
154 }
155 
CheckConnectStatus()156 bool CheckConnectStatus()
157 {
158     int sockfd = -1;
159     std::string name = GetSocketConnectionName();
160     if (StartConnect(sockfd, name.c_str(), -1)) {
161         close(sockfd);
162         return true;
163     }
164     return false;
165 }
166 
SendRequestToServer(const FaultLoggerdRequest & request)167 static int SendRequestToServer(const FaultLoggerdRequest &request)
168 {
169     int sockfd = -1;
170     int resRsp = (int)FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT;
171     do {
172         std::string name = GetSocketConnectionName();
173         if (!StartConnect(sockfd, name.c_str(), -1)) {
174             DFXLOG_ERROR("StartConnect failed.");
175             break;
176         }
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     DFXLOG_INFO("RequestSdkDump :: type(%d), pid(%d), tid(%d).", type, pid, tid);
217     if (pid <= 0 || tid < 0) {
218         return -1;
219     }
220 
221     struct FaultLoggerdRequest request;
222     (void)memset_s(&request, sizeof(request), 0, sizeof(request));
223     request.sigCode = type;
224     request.pid = pid;
225     request.tid = tid;
226     request.callerPid = getpid();
227     request.callerTid = syscall(SYS_gettid);
228     request.clientType = (int32_t)FaultLoggerClientType::SDK_DUMP_CLIENT;
229     request.time = OHOS::HiviewDFX::GetTimeMilliSeconds();
230 
231     return SendRequestToServer(request);
232 }
233 
RequestPrintTHilog(const char * msg,int length)234 int RequestPrintTHilog(const char *msg, int length)
235 {
236     if (length >= LOG_BUF_LEN) {
237         return -1;
238     }
239 
240     struct FaultLoggerdRequest request;
241     (void)memset_s(&request, sizeof(request), 0, sizeof(request));
242     request.clientType = (int32_t)FaultLoggerClientType::PRINT_T_HILOG_CLIENT;
243     request.pid = getpid();
244     request.uid = getuid();
245     int sockfd = -1;
246     do {
247         std::string name = GetSocketConnectionName();
248         if (!StartConnect(sockfd, name.c_str(), -1)) {
249             DFXLOG_ERROR("StartConnect failed");
250             break;
251         }
252 
253         if (write(sockfd, &request, sizeof(struct FaultLoggerdRequest)) != static_cast<long>(sizeof(request))) {
254             break;
255         }
256 
257         if (!CheckReadResp(sockfd)) {
258             break;
259         }
260 
261         int nwrite = write(sockfd, msg, strlen(msg));
262         if (nwrite != static_cast<long>(strlen(msg))) {
263             DFXLOG_ERROR("nwrite: %d.", nwrite);
264             break;
265         }
266         close(sockfd);
267         return 0;
268     } while (false);
269     close(sockfd);
270     return -1;
271 }
272 
RequestPipeFd(int32_t pid,int32_t pipeType)273 int32_t RequestPipeFd(int32_t pid, int32_t pipeType)
274 {
275     if (pipeType < static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_READ_BUF) ||
276         pipeType > static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_WRITE_RES)) {
277         DFXLOG_ERROR("%s :: pipeType(%d) failed.", __func__, pipeType);
278         return -1;
279     }
280     struct FaultLoggerdRequest request;
281     (void)memset_s(&request, sizeof(request), 0, sizeof(struct FaultLoggerdRequest));
282     request.pipeType = pipeType;
283     request.pid = pid;
284     request.callerPid = getpid();
285     request.callerTid = syscall(SYS_gettid);
286     request.clientType = (int32_t)FaultLoggerClientType::PIPE_FD_CLIENT;
287     if ((pipeType == static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_READ_BUF)) ||
288         (pipeType == static_cast<int32_t>(FaultLoggerPipeType::PIPE_FD_READ_RES))) {
289         return RequestFileDescriptorByCheck(&request);
290     }
291     return RequestFileDescriptorEx(&request);
292 }
293 
RequestDelPipeFd(int32_t pid)294 int32_t RequestDelPipeFd(int32_t pid)
295 {
296     struct FaultLoggerdRequest request;
297     (void)memset_s(&request, sizeof(request), 0, sizeof(struct FaultLoggerdRequest));
298     request.pipeType = FaultLoggerPipeType::PIPE_FD_DELETE;
299     request.pid = pid;
300     request.clientType = (int32_t)FaultLoggerClientType::PIPE_FD_CLIENT;
301 
302     int sockfd;
303     std::string name = GetSocketConnectionName();
304     if (!StartConnect(sockfd, name.c_str(), SOCKET_TIMEOUT)) {
305         DFXLOG_ERROR("StartConnect failed");
306         return -1;
307     }
308 
309     write(sockfd, &request, sizeof(struct FaultLoggerdRequest));
310     close(sockfd);
311     return 0;
312 }
313