1 /*
2 * Copyright (C) 2007-2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <endian.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <inttypes.h>
21 #include <poll.h>
22 #include <stdarg.h>
23 #include <stdatomic.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/socket.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <sys/un.h>
31 #include <time.h>
32 #include <unistd.h>
33
34 #include <cutils/sockets.h>
35 #include <private/android_filesystem_config.h>
36 #include <private/android_logger.h>
37
38 #include "config_read.h"
39 #include "log_portability.h"
40 #include "logd_reader.h"
41 #include "logger.h"
42
43 /* branchless on many architectures. */
44 #define min(x, y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
45
46 static int logdAvailable(log_id_t LogId);
47 static int logdVersion(struct android_log_logger* logger,
48 struct android_log_transport_context* transp);
49 static int logdRead(struct android_log_logger_list* logger_list,
50 struct android_log_transport_context* transp, struct log_msg* log_msg);
51 static int logdPoll(struct android_log_logger_list* logger_list,
52 struct android_log_transport_context* transp);
53 static void logdClose(struct android_log_logger_list* logger_list,
54 struct android_log_transport_context* transp);
55 static int logdClear(struct android_log_logger* logger,
56 struct android_log_transport_context* transp);
57 static ssize_t logdSetSize(struct android_log_logger* logger,
58 struct android_log_transport_context* transp, size_t size);
59 static ssize_t logdGetSize(struct android_log_logger* logger,
60 struct android_log_transport_context* transp);
61 static ssize_t logdGetReadableSize(struct android_log_logger* logger,
62 struct android_log_transport_context* transp);
63 static ssize_t logdGetPrune(struct android_log_logger_list* logger,
64 struct android_log_transport_context* transp, char* buf, size_t len);
65 static ssize_t logdSetPrune(struct android_log_logger_list* logger,
66 struct android_log_transport_context* transp, char* buf, size_t len);
67 static ssize_t logdGetStats(struct android_log_logger_list* logger,
68 struct android_log_transport_context* transp, char* buf, size_t len);
69
70 struct android_log_transport_read logdLoggerRead = {
71 .node = {&logdLoggerRead.node, &logdLoggerRead.node},
72 .name = "logd",
73 .available = logdAvailable,
74 .version = logdVersion,
75 .read = logdRead,
76 .poll = logdPoll,
77 .close = logdClose,
78 .clear = logdClear,
79 .getSize = logdGetSize,
80 .setSize = logdSetSize,
81 .getReadableSize = logdGetReadableSize,
82 .getPrune = logdGetPrune,
83 .setPrune = logdSetPrune,
84 .getStats = logdGetStats,
85 };
86
logdAvailable(log_id_t logId)87 static int logdAvailable(log_id_t logId) {
88 if (logId >= LOG_ID_MAX) {
89 return -EINVAL;
90 }
91 if (logId == LOG_ID_SECURITY) {
92 uid_t uid = __android_log_uid();
93 if (uid != AID_SYSTEM) {
94 return -EPERM;
95 }
96 }
97 if (access("/dev/socket/logdw", W_OK) == 0) {
98 return 0;
99 }
100 return -EBADF;
101 }
102
103 // Connects to /dev/socket/<name> and returns the associated fd or returns -1 on error.
104 // O_CLOEXEC is always set.
socket_local_client(const std::string & name,int type)105 static int socket_local_client(const std::string& name, int type) {
106 sockaddr_un addr = {.sun_family = AF_LOCAL};
107
108 std::string path = "/dev/socket/" + name;
109 if (path.size() + 1 > sizeof(addr.sun_path)) {
110 return -1;
111 }
112 strlcpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path));
113
114 int fd = socket(AF_LOCAL, type | SOCK_CLOEXEC, 0);
115 if (fd == 0) {
116 return -1;
117 }
118
119 if (connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
120 close(fd);
121 return -1;
122 }
123
124 return fd;
125 }
126
127 /* worker for sending the command to the logger */
send_log_msg(struct android_log_logger * logger,const char * msg,char * buf,size_t buf_size)128 static ssize_t send_log_msg(struct android_log_logger* logger, const char* msg, char* buf,
129 size_t buf_size) {
130 ssize_t ret;
131 size_t len;
132 char* cp;
133 int errno_save = 0;
134 int sock = socket_local_client("logd", SOCK_STREAM);
135 if (sock < 0) {
136 return sock;
137 }
138
139 if (msg) {
140 snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned)-1);
141 }
142
143 len = strlen(buf) + 1;
144 ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
145 if (ret <= 0) {
146 goto done;
147 }
148
149 len = buf_size;
150 cp = buf;
151 while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
152 struct pollfd p;
153
154 if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
155 break;
156 }
157
158 len -= ret;
159 cp += ret;
160
161 memset(&p, 0, sizeof(p));
162 p.fd = sock;
163 p.events = POLLIN;
164
165 /* Give other side 20ms to refill pipe */
166 ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
167
168 if (ret <= 0) {
169 break;
170 }
171
172 if (!(p.revents & POLLIN)) {
173 ret = 0;
174 break;
175 }
176 }
177
178 if (ret >= 0) {
179 ret += buf_size - len;
180 }
181
182 done:
183 if ((ret == -1) && errno) {
184 errno_save = errno;
185 }
186 close(sock);
187 if (errno_save) {
188 errno = errno_save;
189 }
190 return ret;
191 }
192
__send_log_msg(char * buf,size_t buf_size)193 ssize_t __send_log_msg(char* buf, size_t buf_size) {
194 return send_log_msg(NULL, NULL, buf, buf_size);
195 }
196
check_log_success(char * buf,ssize_t ret)197 static int check_log_success(char* buf, ssize_t ret) {
198 if (ret < 0) {
199 return ret;
200 }
201
202 if (strncmp(buf, "success", 7)) {
203 errno = EINVAL;
204 return -1;
205 }
206
207 return 0;
208 }
209
logdClear(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)210 static int logdClear(struct android_log_logger* logger,
211 struct android_log_transport_context* transp __unused) {
212 char buf[512];
213
214 return check_log_success(buf, send_log_msg(logger, "clear %d", buf, sizeof(buf)));
215 }
216
217 /* returns the total size of the log's ring buffer */
logdGetSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)218 static ssize_t logdGetSize(struct android_log_logger* logger,
219 struct android_log_transport_context* transp __unused) {
220 char buf[512];
221
222 ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));
223 if (ret < 0) {
224 return ret;
225 }
226
227 if ((buf[0] < '0') || ('9' < buf[0])) {
228 return -1;
229 }
230
231 return atol(buf);
232 }
233
logdSetSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused,size_t size)234 static ssize_t logdSetSize(struct android_log_logger* logger,
235 struct android_log_transport_context* transp __unused, size_t size) {
236 char buf[512];
237
238 snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size);
239
240 return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));
241 }
242
243 /*
244 * returns the readable size of the log's ring buffer (that is, amount of the
245 * log consumed)
246 */
logdGetReadableSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)247 static ssize_t logdGetReadableSize(struct android_log_logger* logger,
248 struct android_log_transport_context* transp __unused) {
249 char buf[512];
250
251 ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));
252 if (ret < 0) {
253 return ret;
254 }
255
256 if ((buf[0] < '0') || ('9' < buf[0])) {
257 return -1;
258 }
259
260 return atol(buf);
261 }
262
263 /*
264 * returns the logger version
265 */
logdVersion(struct android_log_logger * logger __unused,struct android_log_transport_context * transp __unused)266 static int logdVersion(struct android_log_logger* logger __unused,
267 struct android_log_transport_context* transp __unused) {
268 uid_t uid = __android_log_uid();
269 return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4;
270 }
271
272 /*
273 * returns statistics
274 */
logdGetStats(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp __unused,char * buf,size_t len)275 static ssize_t logdGetStats(struct android_log_logger_list* logger_list,
276 struct android_log_transport_context* transp __unused, char* buf,
277 size_t len) {
278 struct android_log_logger* logger;
279 char* cp = buf;
280 size_t remaining = len;
281 size_t n;
282
283 n = snprintf(cp, remaining, "getStatistics");
284 n = min(n, remaining);
285 remaining -= n;
286 cp += n;
287
288 logger_for_each(logger, logger_list) {
289 n = snprintf(cp, remaining, " %d", logger->logId);
290 n = min(n, remaining);
291 remaining -= n;
292 cp += n;
293 }
294
295 if (logger_list->pid) {
296 snprintf(cp, remaining, " pid=%u", logger_list->pid);
297 }
298
299 return send_log_msg(NULL, NULL, buf, len);
300 }
301
logdGetPrune(struct android_log_logger_list * logger_list __unused,struct android_log_transport_context * transp __unused,char * buf,size_t len)302 static ssize_t logdGetPrune(struct android_log_logger_list* logger_list __unused,
303 struct android_log_transport_context* transp __unused, char* buf,
304 size_t len) {
305 return send_log_msg(NULL, "getPruneList", buf, len);
306 }
307
logdSetPrune(struct android_log_logger_list * logger_list __unused,struct android_log_transport_context * transp __unused,char * buf,size_t len)308 static ssize_t logdSetPrune(struct android_log_logger_list* logger_list __unused,
309 struct android_log_transport_context* transp __unused, char* buf,
310 size_t len) {
311 const char cmd[] = "setPruneList ";
312 const size_t cmdlen = sizeof(cmd) - 1;
313
314 if (strlen(buf) > (len - cmdlen)) {
315 return -ENOMEM; /* KISS */
316 }
317 memmove(buf + cmdlen, buf, len - cmdlen);
318 buf[len - 1] = '\0';
319 memcpy(buf, cmd, cmdlen);
320
321 return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
322 }
323
caught_signal(int signum __unused)324 static void caught_signal(int signum __unused) {}
325
logdOpen(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp)326 static int logdOpen(struct android_log_logger_list* logger_list,
327 struct android_log_transport_context* transp) {
328 struct android_log_logger* logger;
329 struct sigaction ignore;
330 struct sigaction old_sigaction;
331 unsigned int old_alarm = 0;
332 char buffer[256], *cp, c;
333 int e, ret, remaining, sock;
334
335 if (!logger_list) {
336 return -EINVAL;
337 }
338
339 sock = atomic_load(&transp->context.sock);
340 if (sock > 0) {
341 return sock;
342 }
343
344 sock = socket_local_client("logdr", SOCK_SEQPACKET);
345 if (sock == 0) {
346 /* Guarantee not file descriptor zero */
347 int newsock = socket_local_client("logdr", SOCK_SEQPACKET);
348 close(sock);
349 sock = newsock;
350 }
351 if (sock <= 0) {
352 if ((sock == -1) && errno) {
353 return -errno;
354 }
355 return sock;
356 }
357
358 strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose" : "stream");
359 cp = buffer + strlen(buffer);
360
361 strcpy(cp, " lids");
362 cp += 5;
363 c = '=';
364 remaining = sizeof(buffer) - (cp - buffer);
365 logger_for_each(logger, logger_list) {
366 ret = snprintf(cp, remaining, "%c%u", c, logger->logId);
367 ret = min(ret, remaining);
368 remaining -= ret;
369 cp += ret;
370 c = ',';
371 }
372
373 if (logger_list->tail) {
374 ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);
375 ret = min(ret, remaining);
376 remaining -= ret;
377 cp += ret;
378 }
379
380 if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {
381 if (logger_list->mode & ANDROID_LOG_WRAP) {
382 // ToDo: alternate API to allow timeout to be adjusted.
383 ret = snprintf(cp, remaining, " timeout=%u", ANDROID_LOG_WRAP_DEFAULT_TIMEOUT);
384 ret = min(ret, remaining);
385 remaining -= ret;
386 cp += ret;
387 }
388 ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32, logger_list->start.tv_sec,
389 logger_list->start.tv_nsec);
390 ret = min(ret, remaining);
391 remaining -= ret;
392 cp += ret;
393 }
394
395 if (logger_list->pid) {
396 ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);
397 ret = min(ret, remaining);
398 cp += ret;
399 }
400
401 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
402 /* Deal with an unresponsive logd */
403 memset(&ignore, 0, sizeof(ignore));
404 ignore.sa_handler = caught_signal;
405 sigemptyset(&ignore.sa_mask);
406 /* particularily useful if tombstone is reporting for logd */
407 sigaction(SIGALRM, &ignore, &old_sigaction);
408 old_alarm = alarm(30);
409 }
410 ret = write(sock, buffer, cp - buffer);
411 e = errno;
412 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
413 if (e == EINTR) {
414 e = ETIMEDOUT;
415 }
416 alarm(old_alarm);
417 sigaction(SIGALRM, &old_sigaction, NULL);
418 }
419
420 if (ret <= 0) {
421 close(sock);
422 if ((ret == -1) && e) {
423 return -e;
424 }
425 if (ret == 0) {
426 return -EIO;
427 }
428 return ret;
429 }
430
431 ret = atomic_exchange(&transp->context.sock, sock);
432 if ((ret > 0) && (ret != sock)) {
433 close(ret);
434 }
435 return sock;
436 }
437
438 /* Read from the selected logs */
logdRead(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp,struct log_msg * log_msg)439 static int logdRead(struct android_log_logger_list* logger_list,
440 struct android_log_transport_context* transp, struct log_msg* log_msg) {
441 int ret, e;
442 struct sigaction ignore;
443 struct sigaction old_sigaction;
444 unsigned int old_alarm = 0;
445
446 ret = logdOpen(logger_list, transp);
447 if (ret < 0) {
448 return ret;
449 }
450
451 memset(log_msg, 0, sizeof(*log_msg));
452
453 unsigned int new_alarm = 0;
454 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
455 if ((logger_list->mode & ANDROID_LOG_WRAP) &&
456 (logger_list->start.tv_sec || logger_list->start.tv_nsec)) {
457 /* b/64143705 */
458 new_alarm = (ANDROID_LOG_WRAP_DEFAULT_TIMEOUT * 11) / 10 + 10;
459 logger_list->mode &= ~ANDROID_LOG_WRAP;
460 } else {
461 new_alarm = 30;
462 }
463
464 memset(&ignore, 0, sizeof(ignore));
465 ignore.sa_handler = caught_signal;
466 sigemptyset(&ignore.sa_mask);
467 /* particularily useful if tombstone is reporting for logd */
468 sigaction(SIGALRM, &ignore, &old_sigaction);
469 old_alarm = alarm(new_alarm);
470 }
471
472 /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
473 ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);
474 e = errno;
475
476 if (new_alarm) {
477 if ((ret == 0) || (e == EINTR)) {
478 e = EAGAIN;
479 ret = -1;
480 }
481 alarm(old_alarm);
482 sigaction(SIGALRM, &old_sigaction, NULL);
483 }
484
485 if ((ret == -1) && e) {
486 return -e;
487 }
488 return ret;
489 }
490
logdPoll(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp)491 static int logdPoll(struct android_log_logger_list* logger_list,
492 struct android_log_transport_context* transp) {
493 struct pollfd p;
494
495 int ret = logdOpen(logger_list, transp);
496 if (ret < 0) {
497 return ret;
498 }
499
500 memset(&p, 0, sizeof(p));
501 p.fd = ret;
502 p.events = POLLIN;
503 ret = poll(&p, 1, 20);
504 if ((ret > 0) && !(p.revents & POLLIN)) {
505 ret = 0;
506 }
507 if ((ret == -1) && errno) {
508 return -errno;
509 }
510 return ret;
511 }
512
513 /* Close all the logs */
logdClose(struct android_log_logger_list * logger_list __unused,struct android_log_transport_context * transp)514 static void logdClose(struct android_log_logger_list* logger_list __unused,
515 struct android_log_transport_context* transp) {
516 int sock = atomic_exchange(&transp->context.sock, -1);
517 if (sock > 0) {
518 close(sock);
519 }
520 }
521