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,
51 struct log_msg* log_msg);
52 static int logdPoll(struct android_log_logger_list* logger_list,
53 struct android_log_transport_context* transp);
54 static void logdClose(struct android_log_logger_list* logger_list,
55 struct android_log_transport_context* transp);
56 static int logdClear(struct android_log_logger* logger,
57 struct android_log_transport_context* transp);
58 static ssize_t logdSetSize(struct android_log_logger* logger,
59 struct android_log_transport_context* transp,
60 size_t size);
61 static ssize_t logdGetSize(struct android_log_logger* logger,
62 struct android_log_transport_context* transp);
63 static ssize_t logdGetReadableSize(struct android_log_logger* logger,
64 struct android_log_transport_context* transp);
65 static ssize_t logdGetPrune(struct android_log_logger_list* logger,
66 struct android_log_transport_context* transp,
67 char* buf, size_t len);
68 static ssize_t logdSetPrune(struct android_log_logger_list* logger,
69 struct android_log_transport_context* transp,
70 char* buf, size_t len);
71 static ssize_t logdGetStats(struct android_log_logger_list* logger,
72 struct android_log_transport_context* transp,
73 char* buf, size_t len);
74
75 LIBLOG_HIDDEN struct android_log_transport_read logdLoggerRead = {
76 .node = { &logdLoggerRead.node, &logdLoggerRead.node },
77 .name = "logd",
78 .available = logdAvailable,
79 .version = logdVersion,
80 .read = logdRead,
81 .poll = logdPoll,
82 .close = logdClose,
83 .clear = logdClear,
84 .getSize = logdGetSize,
85 .setSize = logdSetSize,
86 .getReadableSize = logdGetReadableSize,
87 .getPrune = logdGetPrune,
88 .setPrune = logdSetPrune,
89 .getStats = logdGetStats,
90 };
91
logdAvailable(log_id_t logId)92 static int logdAvailable(log_id_t logId) {
93 if (logId >= LOG_ID_MAX) {
94 return -EINVAL;
95 }
96 if (logId == LOG_ID_SECURITY) {
97 uid_t uid = __android_log_uid();
98 if (uid != AID_SYSTEM) {
99 return -EPERM;
100 }
101 }
102 if (access("/dev/socket/logdw", W_OK) == 0) {
103 return 0;
104 }
105 return -EBADF;
106 }
107
108 /* Private copy of ../libcutils/socket_local_client.c prevent library loops */
109
110 #if defined(_WIN32)
111
socket_local_client(const char * name,int namespaceId,int type)112 LIBLOG_WEAK int socket_local_client(const char* name, int namespaceId,
113 int type) {
114 errno = ENOSYS;
115 return -ENOSYS;
116 }
117
118 #else /* !_WIN32 */
119
120 #include <sys/select.h>
121 #include <sys/socket.h>
122 #include <sys/types.h>
123 #include <sys/un.h>
124
125 /* Private copy of ../libcutils/socket_local.h prevent library loops */
126 #define FILESYSTEM_SOCKET_PREFIX "/tmp/"
127 #define ANDROID_RESERVED_SOCKET_PREFIX "/dev/socket/"
128 /* End of ../libcutils/socket_local.h */
129
130 #define LISTEN_BACKLOG 4
131
132 /* Documented in header file. */
socket_make_sockaddr_un(const char * name,int namespaceId,struct sockaddr_un * p_addr,socklen_t * alen)133 LIBLOG_WEAK int socket_make_sockaddr_un(const char* name, int namespaceId,
134 struct sockaddr_un* p_addr,
135 socklen_t* alen) {
136 memset(p_addr, 0, sizeof(*p_addr));
137 size_t namelen;
138
139 switch (namespaceId) {
140 case ANDROID_SOCKET_NAMESPACE_ABSTRACT:
141 #if defined(__linux__)
142 namelen = strlen(name);
143
144 /* Test with length +1 for the *initial* '\0'. */
145 if ((namelen + 1) > sizeof(p_addr->sun_path)) {
146 goto error;
147 }
148
149 /*
150 * Note: The path in this case is *not* supposed to be
151 * '\0'-terminated. ("man 7 unix" for the gory details.)
152 */
153
154 p_addr->sun_path[0] = 0;
155 memcpy(p_addr->sun_path + 1, name, namelen);
156 #else
157 /* this OS doesn't have the Linux abstract namespace */
158
159 namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);
160 /* unix_path_max appears to be missing on linux */
161 if (namelen >
162 sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
163 goto error;
164 }
165
166 strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);
167 strcat(p_addr->sun_path, name);
168 #endif
169 break;
170
171 case ANDROID_SOCKET_NAMESPACE_RESERVED:
172 namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);
173 /* unix_path_max appears to be missing on linux */
174 if (namelen >
175 sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
176 goto error;
177 }
178
179 strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);
180 strcat(p_addr->sun_path, name);
181 break;
182
183 case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:
184 namelen = strlen(name);
185 /* unix_path_max appears to be missing on linux */
186 if (namelen >
187 sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) {
188 goto error;
189 }
190
191 strcpy(p_addr->sun_path, name);
192 break;
193
194 default:
195 /* invalid namespace id */
196 return -1;
197 }
198
199 p_addr->sun_family = AF_LOCAL;
200 *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
201 return 0;
202 error:
203 return -1;
204 }
205
206 /**
207 * connect to peer named "name" on fd
208 * returns same fd or -1 on error.
209 * fd is not closed on error. that's your job.
210 *
211 * Used by AndroidSocketImpl
212 */
socket_local_client_connect(int fd,const char * name,int namespaceId,int type __unused)213 LIBLOG_WEAK int socket_local_client_connect(int fd, const char* name,
214 int namespaceId, int type __unused) {
215 struct sockaddr_un addr;
216 socklen_t alen;
217 int err;
218
219 err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);
220
221 if (err < 0) {
222 goto error;
223 }
224
225 if (connect(fd, (struct sockaddr*)&addr, alen) < 0) {
226 goto error;
227 }
228
229 return fd;
230
231 error:
232 return -1;
233 }
234
235 /**
236 * connect to peer named "name"
237 * returns fd or -1 on error
238 */
socket_local_client(const char * name,int namespaceId,int type)239 LIBLOG_WEAK int socket_local_client(const char* name, int namespaceId,
240 int type) {
241 int s;
242
243 s = socket(AF_LOCAL, type, 0);
244 if (s < 0) return -1;
245
246 if (0 > socket_local_client_connect(s, name, namespaceId, type)) {
247 close(s);
248 return -1;
249 }
250
251 return s;
252 }
253
254 #endif /* !_WIN32 */
255 /* End of ../libcutils/socket_local_client.c */
256
257 /* 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)258 static ssize_t send_log_msg(struct android_log_logger* logger, const char* msg,
259 char* buf, size_t buf_size) {
260 ssize_t ret;
261 size_t len;
262 char* cp;
263 int errno_save = 0;
264 int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
265 SOCK_STREAM);
266 if (sock < 0) {
267 return sock;
268 }
269
270 if (msg) {
271 snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned)-1);
272 }
273
274 len = strlen(buf) + 1;
275 ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
276 if (ret <= 0) {
277 goto done;
278 }
279
280 len = buf_size;
281 cp = buf;
282 while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
283 struct pollfd p;
284
285 if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
286 break;
287 }
288
289 len -= ret;
290 cp += ret;
291
292 memset(&p, 0, sizeof(p));
293 p.fd = sock;
294 p.events = POLLIN;
295
296 /* Give other side 20ms to refill pipe */
297 ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
298
299 if (ret <= 0) {
300 break;
301 }
302
303 if (!(p.revents & POLLIN)) {
304 ret = 0;
305 break;
306 }
307 }
308
309 if (ret >= 0) {
310 ret += buf_size - len;
311 }
312
313 done:
314 if ((ret == -1) && errno) {
315 errno_save = errno;
316 }
317 close(sock);
318 if (errno_save) {
319 errno = errno_save;
320 }
321 return ret;
322 }
323
__send_log_msg(char * buf,size_t buf_size)324 LIBLOG_HIDDEN ssize_t __send_log_msg(char* buf, size_t buf_size) {
325 return send_log_msg(NULL, NULL, buf, buf_size);
326 }
327
check_log_success(char * buf,ssize_t ret)328 static int check_log_success(char* buf, ssize_t ret) {
329 if (ret < 0) {
330 return ret;
331 }
332
333 if (strncmp(buf, "success", 7)) {
334 errno = EINVAL;
335 return -1;
336 }
337
338 return 0;
339 }
340
logdClear(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)341 static int logdClear(struct android_log_logger* logger,
342 struct android_log_transport_context* transp __unused) {
343 char buf[512];
344
345 return check_log_success(buf,
346 send_log_msg(logger, "clear %d", buf, sizeof(buf)));
347 }
348
349 /* returns the total size of the log's ring buffer */
logdGetSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)350 static ssize_t logdGetSize(struct android_log_logger* logger,
351 struct android_log_transport_context* transp __unused) {
352 char buf[512];
353
354 ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));
355 if (ret < 0) {
356 return ret;
357 }
358
359 if ((buf[0] < '0') || ('9' < buf[0])) {
360 return -1;
361 }
362
363 return atol(buf);
364 }
365
logdSetSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused,size_t size)366 static ssize_t logdSetSize(struct android_log_logger* logger,
367 struct android_log_transport_context* transp __unused,
368 size_t size) {
369 char buf[512];
370
371 snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size);
372
373 return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));
374 }
375
376 /*
377 * returns the readable size of the log's ring buffer (that is, amount of the
378 * log consumed)
379 */
logdGetReadableSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)380 static ssize_t logdGetReadableSize(struct android_log_logger* logger,
381 struct android_log_transport_context* transp
382 __unused) {
383 char buf[512];
384
385 ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));
386 if (ret < 0) {
387 return ret;
388 }
389
390 if ((buf[0] < '0') || ('9' < buf[0])) {
391 return -1;
392 }
393
394 return atol(buf);
395 }
396
397 /*
398 * returns the logger version
399 */
logdVersion(struct android_log_logger * logger __unused,struct android_log_transport_context * transp __unused)400 static int logdVersion(struct android_log_logger* logger __unused,
401 struct android_log_transport_context* transp __unused) {
402 uid_t uid = __android_log_uid();
403 return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4;
404 }
405
406 /*
407 * returns statistics
408 */
logdGetStats(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp __unused,char * buf,size_t len)409 static ssize_t logdGetStats(struct android_log_logger_list* logger_list,
410 struct android_log_transport_context* transp __unused,
411 char* buf, size_t len) {
412 struct android_log_logger* logger;
413 char* cp = buf;
414 size_t remaining = len;
415 size_t n;
416
417 n = snprintf(cp, remaining, "getStatistics");
418 n = min(n, remaining);
419 remaining -= n;
420 cp += n;
421
422 logger_for_each(logger, logger_list) {
423 n = snprintf(cp, remaining, " %d", logger->logId);
424 n = min(n, remaining);
425 remaining -= n;
426 cp += n;
427 }
428
429 if (logger_list->pid) {
430 snprintf(cp, remaining, " pid=%u", logger_list->pid);
431 }
432
433 return send_log_msg(NULL, NULL, buf, len);
434 }
435
logdGetPrune(struct android_log_logger_list * logger_list __unused,struct android_log_transport_context * transp __unused,char * buf,size_t len)436 static ssize_t logdGetPrune(struct android_log_logger_list* logger_list __unused,
437 struct android_log_transport_context* transp __unused,
438 char* buf, size_t len) {
439 return send_log_msg(NULL, "getPruneList", buf, len);
440 }
441
logdSetPrune(struct android_log_logger_list * logger_list __unused,struct android_log_transport_context * transp __unused,char * buf,size_t len)442 static ssize_t logdSetPrune(struct android_log_logger_list* logger_list __unused,
443 struct android_log_transport_context* transp __unused,
444 char* buf, size_t len) {
445 const char cmd[] = "setPruneList ";
446 const size_t cmdlen = sizeof(cmd) - 1;
447
448 if (strlen(buf) > (len - cmdlen)) {
449 return -ENOMEM; /* KISS */
450 }
451 memmove(buf + cmdlen, buf, len - cmdlen);
452 buf[len - 1] = '\0';
453 memcpy(buf, cmd, cmdlen);
454
455 return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
456 }
457
caught_signal(int signum __unused)458 static void caught_signal(int signum __unused) {
459 }
460
logdOpen(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp)461 static int logdOpen(struct android_log_logger_list* logger_list,
462 struct android_log_transport_context* transp) {
463 struct android_log_logger* logger;
464 struct sigaction ignore;
465 struct sigaction old_sigaction;
466 unsigned int old_alarm = 0;
467 char buffer[256], *cp, c;
468 int e, ret, remaining, sock;
469
470 if (!logger_list) {
471 return -EINVAL;
472 }
473
474 sock = atomic_load(&transp->context.sock);
475 if (sock > 0) {
476 return sock;
477 }
478
479 sock = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED,
480 SOCK_SEQPACKET);
481 if (sock == 0) {
482 /* Guarantee not file descriptor zero */
483 int newsock = socket_local_client(
484 "logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET);
485 close(sock);
486 sock = newsock;
487 }
488 if (sock <= 0) {
489 if ((sock == -1) && errno) {
490 return -errno;
491 }
492 return sock;
493 }
494
495 strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose"
496 : "stream");
497 cp = buffer + strlen(buffer);
498
499 strcpy(cp, " lids");
500 cp += 5;
501 c = '=';
502 remaining = sizeof(buffer) - (cp - buffer);
503 logger_for_each(logger, logger_list) {
504 ret = snprintf(cp, remaining, "%c%u", c, logger->logId);
505 ret = min(ret, remaining);
506 remaining -= ret;
507 cp += ret;
508 c = ',';
509 }
510
511 if (logger_list->tail) {
512 ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);
513 ret = min(ret, remaining);
514 remaining -= ret;
515 cp += ret;
516 }
517
518 if (logger_list->start.tv_sec || logger_list->start.tv_nsec) {
519 if (logger_list->mode & ANDROID_LOG_WRAP) {
520 // ToDo: alternate API to allow timeout to be adjusted.
521 ret = snprintf(cp, remaining, " timeout=%u",
522 ANDROID_LOG_WRAP_DEFAULT_TIMEOUT);
523 ret = min(ret, remaining);
524 remaining -= ret;
525 cp += ret;
526 }
527 ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32,
528 logger_list->start.tv_sec, logger_list->start.tv_nsec);
529 ret = min(ret, remaining);
530 remaining -= ret;
531 cp += ret;
532 }
533
534 if (logger_list->pid) {
535 ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);
536 ret = min(ret, remaining);
537 cp += ret;
538 }
539
540 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
541 /* Deal with an unresponsive logd */
542 memset(&ignore, 0, sizeof(ignore));
543 ignore.sa_handler = caught_signal;
544 sigemptyset(&ignore.sa_mask);
545 /* particularily useful if tombstone is reporting for logd */
546 sigaction(SIGALRM, &ignore, &old_sigaction);
547 old_alarm = alarm(30);
548 }
549 ret = write(sock, buffer, cp - buffer);
550 e = errno;
551 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
552 if (e == EINTR) {
553 e = ETIMEDOUT;
554 }
555 alarm(old_alarm);
556 sigaction(SIGALRM, &old_sigaction, NULL);
557 }
558
559 if (ret <= 0) {
560 close(sock);
561 if ((ret == -1) && e) {
562 return -e;
563 }
564 if (ret == 0) {
565 return -EIO;
566 }
567 return ret;
568 }
569
570 ret = atomic_exchange(&transp->context.sock, sock);
571 if ((ret > 0) && (ret != sock)) {
572 close(ret);
573 }
574 return sock;
575 }
576
577 /* Read from the selected logs */
logdRead(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp,struct log_msg * log_msg)578 static int logdRead(struct android_log_logger_list* logger_list,
579 struct android_log_transport_context* transp,
580 struct log_msg* log_msg) {
581 int ret, e;
582 struct sigaction ignore;
583 struct sigaction old_sigaction;
584 unsigned int old_alarm = 0;
585
586 ret = logdOpen(logger_list, transp);
587 if (ret < 0) {
588 return ret;
589 }
590
591 memset(log_msg, 0, sizeof(*log_msg));
592
593 unsigned int new_alarm = 0;
594 if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
595 if ((logger_list->mode & ANDROID_LOG_WRAP) &&
596 (logger_list->start.tv_sec || logger_list->start.tv_nsec)) {
597 /* b/64143705 */
598 new_alarm = (ANDROID_LOG_WRAP_DEFAULT_TIMEOUT * 11) / 10 + 10;
599 logger_list->mode &= ~ANDROID_LOG_WRAP;
600 } else {
601 new_alarm = 30;
602 }
603
604 memset(&ignore, 0, sizeof(ignore));
605 ignore.sa_handler = caught_signal;
606 sigemptyset(&ignore.sa_mask);
607 /* particularily useful if tombstone is reporting for logd */
608 sigaction(SIGALRM, &ignore, &old_sigaction);
609 old_alarm = alarm(new_alarm);
610 }
611
612 /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
613 ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);
614 e = errno;
615
616 if (new_alarm) {
617 if ((ret == 0) || (e == EINTR)) {
618 e = EAGAIN;
619 ret = -1;
620 }
621 alarm(old_alarm);
622 sigaction(SIGALRM, &old_sigaction, NULL);
623 }
624
625 if ((ret == -1) && e) {
626 return -e;
627 }
628 return ret;
629 }
630
logdPoll(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp)631 static int logdPoll(struct android_log_logger_list* logger_list,
632 struct android_log_transport_context* transp) {
633 struct pollfd p;
634
635 int ret = logdOpen(logger_list, transp);
636 if (ret < 0) {
637 return ret;
638 }
639
640 memset(&p, 0, sizeof(p));
641 p.fd = ret;
642 p.events = POLLIN;
643 ret = poll(&p, 1, 20);
644 if ((ret > 0) && !(p.revents & POLLIN)) {
645 ret = 0;
646 }
647 if ((ret == -1) && errno) {
648 return -errno;
649 }
650 return ret;
651 }
652
653 /* Close all the logs */
logdClose(struct android_log_logger_list * logger_list __unused,struct android_log_transport_context * transp)654 static void logdClose(struct android_log_logger_list* logger_list __unused,
655 struct android_log_transport_context* transp) {
656 int sock = atomic_exchange(&transp->context.sock, -1);
657 if (sock > 0) {
658 close(sock);
659 }
660 }
661