1 /* 2 * Copyright (C) 2017 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 <errno.h> 18 #include <fcntl.h> 19 #include <pthread.h> 20 #if !defined(__MINGW32__) 21 #include <pwd.h> 22 #endif 23 #include <log/uio.h> 24 #include <sched.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <sys/types.h> 28 29 #include <cutils/list.h> /* template, no library dependency */ 30 #include <log/log_transport.h> 31 #include <private/android_filesystem_config.h> 32 #include <private/android_logger.h> 33 #include <system/thread_defs.h> 34 35 #include "config_read.h" 36 #include "config_write.h" 37 #include "log_portability.h" 38 #include "logger.h" 39 40 static const char baseServiceName[] = "android.logd"; 41 42 static int writeToLocalInit(); 43 static int writeToLocalAvailable(log_id_t logId); 44 static void writeToLocalReset(); 45 static int writeToLocalWrite(log_id_t logId, struct timespec* ts, 46 struct iovec* vec, size_t nr); 47 48 LIBLOG_HIDDEN struct android_log_transport_write localLoggerWrite = { 49 .node = { &localLoggerWrite.node, &localLoggerWrite.node }, 50 .context.priv = NULL, 51 .name = "local", 52 .available = writeToLocalAvailable, 53 .open = writeToLocalInit, 54 .close = writeToLocalReset, 55 .write = writeToLocalWrite, 56 }; 57 58 static int writeToLocalVersion(struct android_log_logger* logger, 59 struct android_log_transport_context* transp); 60 static int writeToLocalRead(struct android_log_logger_list* logger_list, 61 struct android_log_transport_context* transp, 62 struct log_msg* log_msg); 63 static int writeToLocalPoll(struct android_log_logger_list* logger_list, 64 struct android_log_transport_context* transp); 65 static void writeToLocalClose(struct android_log_logger_list* logger_list, 66 struct android_log_transport_context* transp); 67 static int writeToLocalClear(struct android_log_logger* logger, 68 struct android_log_transport_context* transp); 69 static ssize_t writeToLocalGetSize(struct android_log_logger* logger, 70 struct android_log_transport_context* transp); 71 static ssize_t writeToLocalSetSize( 72 struct android_log_logger* logger, 73 struct android_log_transport_context* transp __unused, size_t size); 74 static ssize_t writeToLocalGetReadbleSize( 75 struct android_log_logger* logger, 76 struct android_log_transport_context* transp); 77 78 struct android_log_transport_read localLoggerRead = { 79 .node = { &localLoggerRead.node, &localLoggerRead.node }, 80 .name = "local", 81 .available = writeToLocalAvailable, 82 .version = writeToLocalVersion, 83 .read = writeToLocalRead, 84 .poll = writeToLocalPoll, 85 .close = writeToLocalClose, 86 .clear = writeToLocalClear, 87 .getSize = writeToLocalGetSize, 88 .setSize = writeToLocalSetSize, 89 .getReadableSize = writeToLocalGetReadbleSize, 90 .getPrune = NULL, 91 .setPrune = NULL, 92 .getStats = NULL, 93 }; 94 95 struct LogBufferElement { 96 struct listnode node; 97 log_id_t logId; 98 pid_t tid; 99 log_time timestamp; 100 unsigned short len; 101 char msg[]; 102 }; 103 104 static const size_t MAX_SIZE_DEFAULT = 32768; 105 106 /* 107 * Number of log buffers we support with the following assumption: 108 * . . . 109 * LOG_ID_SECURITY = 5, // security logs go to the system logs only 110 * LOG_ID_KERNEL = 6, // place last, third-parties can not use it 111 * LOG_ID_MAX 112 * } log_id_t; 113 * 114 * Confirm the following should <log/log_id.h> be adjusted in the future. 115 */ 116 #define NUMBER_OF_LOG_BUFFERS \ 117 ((LOG_ID_SECURITY == (LOG_ID_MAX - 2)) ? LOG_ID_SECURITY : LOG_ID_KERNEL) 118 #define BLOCK_LOG_BUFFERS(id) \ 119 (((id) == LOG_ID_SECURITY) || ((id) == LOG_ID_KERNEL)) 120 121 static struct LogBuffer { 122 struct listnode head; 123 pthread_rwlock_t listLock; 124 char* serviceName; /* Also indicates ready by having a value */ 125 /* Order and proximity important for memset */ 126 size_t number[NUMBER_OF_LOG_BUFFERS]; /* clear memset */ 127 size_t size[NUMBER_OF_LOG_BUFFERS]; /* clear memset */ 128 size_t totalSize[NUMBER_OF_LOG_BUFFERS]; /* init memset */ 129 size_t maxSize[NUMBER_OF_LOG_BUFFERS]; /* init MAX_SIZE_DEFAULT */ 130 struct listnode* last[NUMBER_OF_LOG_BUFFERS]; /* init &head */ 131 } logbuf = { 132 .head = { &logbuf.head, &logbuf.head }, .listLock = PTHREAD_RWLOCK_INITIALIZER, 133 }; 134 135 static void LogBufferInit(struct LogBuffer* log) { 136 size_t i; 137 138 pthread_rwlock_wrlock(&log->listLock); 139 list_init(&log->head); 140 memset(log->number, 0, 141 sizeof(log->number) + sizeof(log->size) + sizeof(log->totalSize)); 142 for (i = 0; i < NUMBER_OF_LOG_BUFFERS; ++i) { 143 log->maxSize[i] = MAX_SIZE_DEFAULT; 144 log->last[i] = &log->head; 145 } 146 #ifdef __BIONIC__ 147 asprintf(&log->serviceName, "%s@%d:%d", baseServiceName, __android_log_uid(), 148 getpid()); 149 #else 150 char buffer[sizeof(baseServiceName) + 1 + 5 + 1 + 5 + 8]; 151 snprintf(buffer, sizeof(buffer), "%s@%d:%d", baseServiceName, 152 __android_log_uid(), getpid()); 153 log->serviceName = strdup(buffer); 154 #endif 155 pthread_rwlock_unlock(&log->listLock); 156 } 157 158 static void LogBufferClear(struct LogBuffer* log) { 159 size_t i; 160 struct listnode* node; 161 162 pthread_rwlock_wrlock(&log->listLock); 163 memset(log->number, 0, sizeof(log->number) + sizeof(log->size)); 164 for (i = 0; i < NUMBER_OF_LOG_BUFFERS; ++i) { 165 log->last[i] = &log->head; 166 } 167 while ((node = list_head(&log->head)) != &log->head) { 168 struct LogBufferElement* element; 169 170 element = node_to_item(node, struct LogBufferElement, node); 171 list_remove(node); 172 free(element); 173 } 174 pthread_rwlock_unlock(&log->listLock); 175 } 176 177 static inline void LogBufferFree(struct LogBuffer* log) { 178 pthread_rwlock_wrlock(&log->listLock); 179 free(log->serviceName); 180 log->serviceName = NULL; 181 pthread_rwlock_unlock(&log->listLock); 182 LogBufferClear(log); 183 } 184 185 static int LogBufferLog(struct LogBuffer* log, 186 struct LogBufferElement* element) { 187 log_id_t logId = element->logId; 188 189 pthread_rwlock_wrlock(&log->listLock); 190 log->number[logId]++; 191 log->size[logId] += element->len; 192 log->totalSize[logId] += element->len; 193 /* prune entry(s) until enough space is available */ 194 if (log->last[logId] == &log->head) { 195 log->last[logId] = list_tail(&log->head); 196 } 197 while (log->size[logId] > log->maxSize[logId]) { 198 struct listnode* node = log->last[logId]; 199 struct LogBufferElement* e; 200 struct android_log_logger_list* logger_list; 201 202 e = node_to_item(node, struct LogBufferElement, node); 203 log->number[logId]--; 204 log->size[logId] -= e->len; 205 logger_list_rdlock(); 206 logger_list_for_each(logger_list) { 207 struct android_log_transport_context* transp; 208 209 transport_context_for_each(transp, logger_list) { 210 if ((transp->transport == &localLoggerRead) && 211 (transp->context.node == node)) { 212 if (node == &log->head) { 213 transp->context.node = &log->head; 214 } else { 215 transp->context.node = node->next; 216 } 217 } 218 } 219 } 220 logger_list_unlock(); 221 if (node != &log->head) { 222 log->last[logId] = node->prev; 223 } 224 list_remove(node); 225 LOG_ALWAYS_FATAL_IF(node == log->last[logId], "corrupted list"); 226 free(e); 227 } 228 /* add entry to list */ 229 list_add_head(&log->head, &element->node); 230 /* ToDo: wake up all readers */ 231 pthread_rwlock_unlock(&log->listLock); 232 233 return element->len; 234 } 235 236 /* 237 * return zero if permitted to log directly to logd, 238 * return 1 if binder server started and 239 * return negative error number if failed to start binder server. 240 */ 241 static int writeToLocalInit() { 242 pthread_attr_t attr; 243 struct LogBuffer* log; 244 245 if (writeToLocalAvailable(LOG_ID_MAIN) < 0) { 246 return -EPERM; 247 } 248 249 log = &logbuf; 250 if (!log->serviceName) { 251 LogBufferInit(log); 252 } 253 254 if (!log->serviceName) { 255 LogBufferFree(log); 256 return -ENOMEM; 257 } 258 259 return EPERM; /* successful local-only logging */ 260 } 261 262 static void writeToLocalReset() { 263 LogBufferFree(&logbuf); 264 } 265 266 static int writeToLocalAvailable(log_id_t logId) { 267 #if !defined(__MINGW32__) 268 uid_t uid; 269 #endif 270 271 if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) { 272 return -EINVAL; 273 } 274 275 /* Android hard coded permitted, system goes to logd */ 276 #if !defined(__MINGW32__) 277 if (__android_log_transport == LOGGER_DEFAULT) { 278 uid = __android_log_uid(); 279 if ((uid < AID_APP) && (getpwuid(uid) != NULL)) { 280 return -EPERM; 281 } 282 } 283 #endif 284 285 /* ToDo: Ask package manager for LOGD permissions */ 286 /* Assume we do _not_ have permissions to go to LOGD, so must go local */ 287 return 0; 288 } 289 290 static int writeToLocalWrite(log_id_t logId, struct timespec* ts, 291 struct iovec* vec, size_t nr) { 292 size_t len, i; 293 struct LogBufferElement* element; 294 295 if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) { 296 return -EINVAL; 297 } 298 299 len = 0; 300 for (i = 0; i < nr; ++i) { 301 len += vec[i].iov_len; 302 } 303 304 if (len > LOGGER_ENTRY_MAX_PAYLOAD) { 305 len = LOGGER_ENTRY_MAX_PAYLOAD; 306 } 307 element = (struct LogBufferElement*)calloc( 308 1, sizeof(struct LogBufferElement) + len + 1); 309 if (!element) { 310 return errno ? -errno : -ENOMEM; 311 } 312 element->timestamp.tv_sec = ts->tv_sec; 313 element->timestamp.tv_nsec = ts->tv_nsec; 314 #ifdef __BIONIC__ 315 element->tid = gettid(); 316 #else 317 element->tid = getpid(); 318 #endif 319 element->logId = logId; 320 element->len = len; 321 322 char* cp = element->msg; 323 for (i = 0; i < nr; ++i) { 324 size_t iov_len = vec[i].iov_len; 325 if (iov_len > len) { 326 iov_len = len; 327 } 328 memcpy(cp, vec[i].iov_base, iov_len); 329 len -= iov_len; 330 if (len == 0) { 331 break; 332 } 333 cp += iov_len; 334 } 335 336 return LogBufferLog(&logbuf, element); 337 } 338 339 static int writeToLocalVersion(struct android_log_logger* logger __unused, 340 struct android_log_transport_context* transp 341 __unused) { 342 return 3; 343 } 344 345 /* within reader lock, serviceName already validated */ 346 static struct listnode* writeToLocalNode( 347 struct android_log_logger_list* logger_list, 348 struct android_log_transport_context* transp) { 349 struct listnode* node; 350 unsigned logMask; 351 unsigned int tail; 352 353 node = transp->context.node; 354 if (node) { 355 return node; 356 } 357 358 if (!logger_list->tail) { 359 return transp->context.node = &logbuf.head; 360 } 361 362 logMask = transp->logMask; 363 tail = logger_list->tail; 364 365 for (node = list_head(&logbuf.head); node != &logbuf.head; node = node->next) { 366 struct LogBufferElement* element; 367 log_id_t logId; 368 369 element = node_to_item(node, struct LogBufferElement, node); 370 logId = element->logId; 371 372 if ((logMask & (1 << logId)) && !--tail) { 373 node = node->next; 374 break; 375 } 376 } 377 return transp->context.node = node; 378 } 379 380 static int writeToLocalRead(struct android_log_logger_list* logger_list, 381 struct android_log_transport_context* transp, 382 struct log_msg* log_msg) { 383 int ret; 384 struct listnode* node; 385 unsigned logMask; 386 387 pthread_rwlock_rdlock(&logbuf.listLock); 388 if (!logbuf.serviceName) { 389 pthread_rwlock_unlock(&logbuf.listLock); 390 return (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0; 391 } 392 393 logMask = transp->logMask; 394 395 node = writeToLocalNode(logger_list, transp); 396 397 ret = 0; 398 399 while (node != list_head(&logbuf.head)) { 400 struct LogBufferElement* element; 401 log_id_t logId; 402 403 node = node->prev; 404 element = node_to_item(node, struct LogBufferElement, node); 405 logId = element->logId; 406 407 if (logMask & (1 << logId)) { 408 ret = log_msg->entry_v3.len = element->len; 409 log_msg->entry_v3.hdr_size = sizeof(log_msg->entry_v3); 410 log_msg->entry_v3.pid = getpid(); 411 log_msg->entry_v3.tid = element->tid; 412 log_msg->entry_v3.sec = element->timestamp.tv_sec; 413 log_msg->entry_v3.nsec = element->timestamp.tv_nsec; 414 log_msg->entry_v3.lid = logId; 415 memcpy(log_msg->entry_v3.msg, element->msg, ret); 416 ret += log_msg->entry_v3.hdr_size; 417 break; 418 } 419 } 420 421 transp->context.node = node; 422 423 /* ToDo: if blocking, and no entry, put reader to sleep */ 424 pthread_rwlock_unlock(&logbuf.listLock); 425 return ret; 426 } 427 428 static int writeToLocalPoll(struct android_log_logger_list* logger_list, 429 struct android_log_transport_context* transp) { 430 int ret = (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0; 431 432 pthread_rwlock_rdlock(&logbuf.listLock); 433 434 if (logbuf.serviceName) { 435 unsigned logMask = transp->logMask; 436 struct listnode* node = writeToLocalNode(logger_list, transp); 437 438 ret = (node != list_head(&logbuf.head)); 439 if (ret) { 440 do { 441 ret = !!(logMask & 442 (1 << (node_to_item(node->prev, struct LogBufferElement, node)) 443 ->logId)); 444 } while (!ret && ((node = node->prev) != list_head(&logbuf.head))); 445 } 446 447 transp->context.node = node; 448 } 449 450 pthread_rwlock_unlock(&logbuf.listLock); 451 452 return ret; 453 } 454 455 static void writeToLocalClose(struct android_log_logger_list* logger_list 456 __unused, 457 struct android_log_transport_context* transp) { 458 pthread_rwlock_wrlock(&logbuf.listLock); 459 transp->context.node = list_head(&logbuf.head); 460 pthread_rwlock_unlock(&logbuf.listLock); 461 } 462 463 static int writeToLocalClear(struct android_log_logger* logger, 464 struct android_log_transport_context* unused 465 __unused) { 466 log_id_t logId = logger->logId; 467 struct listnode *node, *n; 468 469 if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) { 470 return -EINVAL; 471 } 472 473 pthread_rwlock_wrlock(&logbuf.listLock); 474 logbuf.number[logId] = 0; 475 logbuf.last[logId] = &logbuf.head; 476 list_for_each_safe(node, n, &logbuf.head) { 477 struct LogBufferElement* element; 478 element = node_to_item(node, struct LogBufferElement, node); 479 480 if (logId == element->logId) { 481 struct android_log_logger_list* logger_list; 482 483 logger_list_rdlock(); 484 logger_list_for_each(logger_list) { 485 struct android_log_transport_context* transp; 486 487 transport_context_for_each(transp, logger_list) { 488 if ((transp->transport == &localLoggerRead) && 489 (transp->context.node == node)) { 490 transp->context.node = node->next; 491 } 492 } 493 } 494 logger_list_unlock(); 495 list_remove(node); 496 free(element); 497 } 498 } 499 500 pthread_rwlock_unlock(&logbuf.listLock); 501 502 return 0; 503 } 504 505 static ssize_t writeToLocalGetSize(struct android_log_logger* logger, 506 struct android_log_transport_context* transp 507 __unused) { 508 ssize_t ret = -EINVAL; 509 log_id_t logId = logger->logId; 510 511 if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) { 512 pthread_rwlock_rdlock(&logbuf.listLock); 513 ret = logbuf.maxSize[logId]; 514 pthread_rwlock_unlock(&logbuf.listLock); 515 } 516 517 return ret; 518 } 519 520 static ssize_t writeToLocalSetSize( 521 struct android_log_logger* logger, 522 struct android_log_transport_context* transp __unused, size_t size) { 523 ssize_t ret = -EINVAL; 524 525 if ((size > LOGGER_ENTRY_MAX_LEN) || (size < (4 * 1024 * 1024))) { 526 log_id_t logId = logger->logId; 527 if ((logId < NUMBER_OF_LOG_BUFFERS) || !BLOCK_LOG_BUFFERS(logId)) { 528 pthread_rwlock_wrlock(&logbuf.listLock); 529 ret = logbuf.maxSize[logId] = size; 530 pthread_rwlock_unlock(&logbuf.listLock); 531 } 532 } 533 534 return ret; 535 } 536 537 static ssize_t writeToLocalGetReadbleSize( 538 struct android_log_logger* logger, 539 struct android_log_transport_context* transp __unused) { 540 ssize_t ret = -EINVAL; 541 log_id_t logId = logger->logId; 542 543 if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) { 544 pthread_rwlock_rdlock(&logbuf.listLock); 545 ret = logbuf.serviceName ? (ssize_t)logbuf.size[logId] : -EBADF; 546 pthread_rwlock_unlock(&logbuf.listLock); 547 } 548 549 return ret; 550 } 551