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