blob: 4999aef0d920f01d3800e1cb7f8bd9bfa184e58e [file] [log] [blame]
Mark Salyzyn018a96d2016-03-01 13:45:42 -08001/*
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 <errno.h>
18#include <stdatomic.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/time.h>
22
23#ifdef __BIONIC__
24#include <android/set_abort_message.h>
25#endif
26
Mark Salyzyn6584d0a2016-09-28 13:26:55 -070027#include <android/log.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080028#include <log/event_tag_map.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080029#include <log/logger.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080030#include <private/android_filesystem_config.h>
31#include <private/android_logger.h>
32
33#include "config_write.h"
34#include "log_portability.h"
35#include "logger.h"
36
37#define LOG_BUF_SIZE 1024
38
39static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);
40static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;
41
42/*
43 * This is used by the C++ code to decide if it should write logs through
44 * the C code. Basically, if /dev/socket/logd is available, we're running in
45 * the simulator rather than a desktop tool and want to use the device.
46 */
47static enum {
48 kLogUninitialized, kLogNotAvailable, kLogAvailable
49} g_log_status = kLogUninitialized;
50
Mark Salyzync33103c2016-03-28 16:20:29 -070051static int check_log_uid_permissions()
52{
53#if defined(__BIONIC__)
54 uid_t uid = __android_log_uid();
55
56 /* Matches clientHasLogCredentials() in logd */
57 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
58 uid = geteuid();
59 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
60 gid_t gid = getgid();
61 if ((gid != AID_SYSTEM) &&
62 (gid != AID_ROOT) &&
63 (gid != AID_LOG)) {
64 gid = getegid();
65 if ((gid != AID_SYSTEM) &&
66 (gid != AID_ROOT) &&
67 (gid != AID_LOG)) {
68 int num_groups;
69 gid_t *groups;
70
71 num_groups = getgroups(0, NULL);
72 if (num_groups <= 0) {
73 return -EPERM;
74 }
75 groups = calloc(num_groups, sizeof(gid_t));
76 if (!groups) {
77 return -ENOMEM;
78 }
79 num_groups = getgroups(num_groups, groups);
80 while (num_groups > 0) {
81 if (groups[num_groups - 1] == AID_LOG) {
82 break;
83 }
84 --num_groups;
85 }
86 free(groups);
87 if (num_groups <= 0) {
88 return -EPERM;
89 }
90 }
91 }
92 }
93 }
94#endif
95 return 0;
96}
97
98static void __android_log_cache_available(
99 struct android_log_transport_write *node)
100{
101 size_t i;
102
103 if (node->logMask) {
104 return;
105 }
106
107 for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
108 if (node->write &&
109 (i != LOG_ID_KERNEL) &&
110 ((i != LOG_ID_SECURITY) ||
111 (check_log_uid_permissions() == 0)) &&
112 (!node->available || ((*node->available)(i) >= 0))) {
113 node->logMask |= 1 << i;
114 }
115 }
116}
117
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800118LIBLOG_ABI_PUBLIC int __android_log_dev_available()
119{
120 struct android_log_transport_write *node;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800121
122 if (list_empty(&__android_log_transport_write)) {
123 return kLogUninitialized;
124 }
Mark Salyzync33103c2016-03-28 16:20:29 -0700125
126 write_transport_for_each(node, &__android_log_transport_write) {
127 __android_log_cache_available(node);
128 if (node->logMask) {
129 return kLogAvailable;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800130 }
131 }
132 return kLogNotAvailable;
133}
Mark Salyzynba1a7982016-09-13 07:28:21 -0700134
135#if defined(__BIONIC__)
136static atomic_uintptr_t tagMap;
137#endif
138
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700139/*
140 * Release any logger resources. A new log write will immediately re-acquire.
141 */
142LIBLOG_ABI_PUBLIC void __android_log_close()
143{
144 struct android_log_transport_write *transport;
Mark Salyzynba1a7982016-09-13 07:28:21 -0700145#if defined(__BIONIC__)
146 EventTagMap *m;
147#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700148
149 __android_log_lock();
150
151 write_to_log = __write_to_log_init;
152
153 /*
154 * Threads that are actively writing at this point are not held back
155 * by a lock and are at risk of dropping the messages with a return code
156 * -EBADF. Prefer to return error code than add the overhead of a lock to
157 * each log writing call to guarantee delivery. In addition, anyone
158 * calling this is doing so to release the logging resources and shut down,
159 * for them to do so with outstanding log requests in other threads is a
160 * disengenuous use of this function.
161 */
162
163 write_transport_for_each(transport, &__android_log_persist_write) {
164 if (transport->close) {
165 (*transport->close)();
166 }
167 }
168
169 write_transport_for_each(transport, &__android_log_transport_write) {
170 if (transport->close) {
171 (*transport->close)();
172 }
173 }
174
Mark Salyzynba1a7982016-09-13 07:28:21 -0700175#if defined(__BIONIC__)
176 /*
177 * Additional risk here somewhat mitigated by immediately unlock flushing
178 * the processor cache. The multi-threaded race that we choose to accept,
179 * to minimize locking, is an atomic_load in a writer picking up a value
180 * just prior to entering this routine. There will be an use after free.
181 *
182 * Again, anyone calling this is doing so to release the logging resources
183 * is most probably going to quiesce then shut down; or to restart after
184 * a fork so the risk should be non-existent. For this reason we
185 * choose a mitigation stance for efficiency instead of incuring the cost
186 * of a lock for every log write.
187 */
188 m = (EventTagMap *)atomic_exchange(&tagMap, (uintptr_t)0);
189#endif
190
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700191 __android_log_unlock();
Mark Salyzynba1a7982016-09-13 07:28:21 -0700192
193#if defined(__BIONIC__)
194 android_closeEventTagMap(m);
195#endif
196
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700197}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800198
199/* log_init_lock assumed */
200static int __write_to_log_initialize()
201{
202 struct android_log_transport_write *transport;
203 struct listnode *n;
204 int i = 0, ret = 0;
205
206 __android_log_config_write();
207 write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700208 __android_log_cache_available(transport);
209 if (!transport->logMask) {
210 list_remove(&transport->node);
211 continue;
212 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800213 if (!transport->open || ((*transport->open)() < 0)) {
214 if (transport->close) {
215 (*transport->close)();
216 }
217 list_remove(&transport->node);
218 continue;
219 }
220 ++ret;
221 }
222 write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700223 __android_log_cache_available(transport);
224 if (!transport->logMask) {
225 list_remove(&transport->node);
226 continue;
227 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800228 if (!transport->open || ((*transport->open)() < 0)) {
229 if (transport->close) {
230 (*transport->close)();
231 }
232 list_remove(&transport->node);
233 continue;
234 }
235 ++i;
236 }
237 if (!ret && !i) {
238 return -ENODEV;
239 }
240
241 return ret;
242}
243
244/*
245 * Extract a 4-byte value from a byte stream. le32toh open coded
246 */
247static inline uint32_t get4LE(const uint8_t* src)
248{
249 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
250}
251
252static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
253{
254 struct android_log_transport_write *node;
255 int ret;
256 struct timespec ts;
257 size_t len, i;
258
259 for (len = i = 0; i < nr; ++i) {
260 len += vec[i].iov_len;
261 }
262 if (!len) {
263 return -EINVAL;
264 }
265
266#if defined(__BIONIC__)
267 if (log_id == LOG_ID_SECURITY) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800268 if (vec[0].iov_len < 4) {
269 return -EINVAL;
270 }
271
Mark Salyzync33103c2016-03-28 16:20:29 -0700272 ret = check_log_uid_permissions();
273 if (ret < 0) {
274 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800275 }
276 if (!__android_log_security()) {
277 /* If only we could reset downstream logd counter */
278 return -EPERM;
279 }
280 } else if (log_id == LOG_ID_EVENTS) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800281 const char *tag;
282 EventTagMap *m, *f;
283
284 if (vec[0].iov_len < 4) {
285 return -EINVAL;
286 }
287
288 tag = NULL;
289 f = NULL;
Mark Salyzynba1a7982016-09-13 07:28:21 -0700290 m = (EventTagMap *)atomic_load(&tagMap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800291
292 if (!m) {
293 ret = __android_log_trylock();
Mark Salyzynba1a7982016-09-13 07:28:21 -0700294 m = (EventTagMap *)atomic_load(&tagMap); /* trylock flush cache */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800295 if (!m) {
296 m = android_openEventTagMap(EVENT_TAG_MAP_FILE);
297 if (ret) { /* trylock failed, use local copy, mark for close */
298 f = m;
299 } else {
300 if (!m) { /* One chance to open map file */
301 m = (EventTagMap *)(uintptr_t)-1LL;
302 }
Mark Salyzynba1a7982016-09-13 07:28:21 -0700303 atomic_store(&tagMap, (uintptr_t)m);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800304 }
305 }
306 if (!ret) { /* trylock succeeded, unlock */
307 __android_log_unlock();
308 }
309 }
310 if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) {
311 tag = android_lookupEventTag(m, get4LE(vec[0].iov_base));
312 }
313 ret = __android_log_is_loggable(ANDROID_LOG_INFO,
314 tag,
315 ANDROID_LOG_VERBOSE);
316 if (f) { /* local copy marked for close */
317 android_closeEventTagMap(f);
318 }
319 if (!ret) {
320 return -EPERM;
321 }
322 } else {
323 /* Validate the incoming tag, tag content can not split across iovec */
324 char prio = ANDROID_LOG_VERBOSE;
325 const char *tag = vec[0].iov_base;
326 size_t len = vec[0].iov_len;
327 if (!tag) {
328 len = 0;
329 }
330 if (len > 0) {
331 prio = *tag;
332 if (len > 1) {
333 --len;
334 ++tag;
335 } else {
336 len = vec[1].iov_len;
337 tag = ((const char *)vec[1].iov_base);
338 if (!tag) {
339 len = 0;
340 }
341 }
342 }
343 /* tag must be nul terminated */
344 if (strnlen(tag, len) >= len) {
345 tag = NULL;
346 }
347
348 if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
349 return -EPERM;
350 }
351 }
352
353 clock_gettime(android_log_clockid(), &ts);
354#else
355 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
356 {
357 struct timeval tv;
358 gettimeofday(&tv, NULL);
359 ts.tv_sec = tv.tv_sec;
360 ts.tv_nsec = tv.tv_usec * 1000;
361 }
362#endif
363
364 ret = 0;
Mark Salyzync33103c2016-03-28 16:20:29 -0700365 i = 1 << log_id;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800366 write_transport_for_each(node, &__android_log_transport_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700367 if (node->logMask & i) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800368 ssize_t retval;
369 retval = (*node->write)(log_id, &ts, vec, nr);
370 if (ret >= 0) {
371 ret = retval;
372 }
373 }
374 }
375
376 write_transport_for_each(node, &__android_log_persist_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700377 if (node->logMask & i) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800378 (void)(*node->write)(log_id, &ts, vec, nr);
379 }
380 }
381
382 return ret;
383}
384
385static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)
386{
387 __android_log_lock();
388
389 if (write_to_log == __write_to_log_init) {
390 int ret;
391
392 ret = __write_to_log_initialize();
393 if (ret < 0) {
394 __android_log_unlock();
395 if (!list_empty(&__android_log_persist_write)) {
396 __write_to_log_daemon(log_id, vec, nr);
397 }
398 return ret;
399 }
400
401 write_to_log = __write_to_log_daemon;
402 }
403
404 __android_log_unlock();
405
406 return write_to_log(log_id, vec, nr);
407}
408
409LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag,
410 const char *msg)
411{
412 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
413}
414
415LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
416 const char *tag, const char *msg)
417{
418 struct iovec vec[3];
419 char tmp_tag[32];
420
421 if (!tag)
422 tag = "";
423
424 /* XXX: This needs to go! */
425 if ((bufID != LOG_ID_RADIO) &&
426 (!strcmp(tag, "HTC_RIL") ||
427 !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
428 !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
429 !strcmp(tag, "AT") ||
430 !strcmp(tag, "GSM") ||
431 !strcmp(tag, "STK") ||
432 !strcmp(tag, "CDMA") ||
433 !strcmp(tag, "PHONE") ||
434 !strcmp(tag, "SMS"))) {
435 bufID = LOG_ID_RADIO;
436 /* Inform third party apps/ril/radio.. to use Rlog or RLOG */
437 snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
438 tag = tmp_tag;
439 }
440
441#if __BIONIC__
442 if (prio == ANDROID_LOG_FATAL) {
443 android_set_abort_message(msg);
444 }
445#endif
446
Mark Salyzync33103c2016-03-28 16:20:29 -0700447 vec[0].iov_base = (unsigned char *)&prio;
448 vec[0].iov_len = 1;
449 vec[1].iov_base = (void *)tag;
450 vec[1].iov_len = strlen(tag) + 1;
451 vec[2].iov_base = (void *)msg;
452 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800453
454 return write_to_log(bufID, vec, 3);
455}
456
457LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char *tag,
458 const char *fmt, va_list ap)
459{
460 char buf[LOG_BUF_SIZE];
461
462 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
463
464 return __android_log_write(prio, tag, buf);
465}
466
467LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char *tag,
468 const char *fmt, ...)
469{
470 va_list ap;
471 char buf[LOG_BUF_SIZE];
472
473 va_start(ap, fmt);
474 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
475 va_end(ap);
476
477 return __android_log_write(prio, tag, buf);
478}
479
480LIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio,
481 const char *tag,
482 const char *fmt, ...)
483{
484 va_list ap;
485 char buf[LOG_BUF_SIZE];
486
487 va_start(ap, fmt);
488 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
489 va_end(ap);
490
491 return __android_log_buf_write(bufID, prio, tag, buf);
492}
493
494LIBLOG_ABI_PUBLIC void __android_log_assert(const char *cond, const char *tag,
495 const char *fmt, ...)
496{
497 char buf[LOG_BUF_SIZE];
498
499 if (fmt) {
500 va_list ap;
501 va_start(ap, fmt);
502 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
503 va_end(ap);
504 } else {
505 /* Msg not provided, log condition. N.B. Do not use cond directly as
506 * format string as it could contain spurious '%' syntax (e.g.
507 * "%d" in "blocks%devs == 0").
508 */
509 if (cond)
510 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
511 else
512 strcpy(buf, "Unspecified assertion failed");
513 }
514
515 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
516 abort(); /* abort so we have a chance to debug the situation */
517 /* NOTREACHED */
518}
519
520LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag,
521 const void *payload, size_t len)
522{
523 struct iovec vec[2];
524
525 vec[0].iov_base = &tag;
526 vec[0].iov_len = sizeof(tag);
527 vec[1].iov_base = (void*)payload;
528 vec[1].iov_len = len;
529
530 return write_to_log(LOG_ID_EVENTS, vec, 2);
531}
532
533LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag,
534 const void *payload,
535 size_t len)
536{
537 struct iovec vec[2];
538
539 vec[0].iov_base = &tag;
540 vec[0].iov_len = sizeof(tag);
541 vec[1].iov_base = (void*)payload;
542 vec[1].iov_len = len;
543
544 return write_to_log(LOG_ID_SECURITY, vec, 2);
545}
546
547/*
548 * Like __android_log_bwrite, but takes the type as well. Doesn't work
549 * for the general case where we're generating lists of stuff, but very
550 * handy if we just want to dump an integer into the log.
551 */
552LIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type,
553 const void *payload, size_t len)
554{
555 struct iovec vec[3];
556
557 vec[0].iov_base = &tag;
558 vec[0].iov_len = sizeof(tag);
559 vec[1].iov_base = &type;
560 vec[1].iov_len = sizeof(type);
561 vec[2].iov_base = (void*)payload;
562 vec[2].iov_len = len;
563
564 return write_to_log(LOG_ID_EVENTS, vec, 3);
565}
566
567/*
568 * Like __android_log_bwrite, but used for writing strings to the
569 * event log.
570 */
571LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload)
572{
573 struct iovec vec[4];
574 char type = EVENT_TYPE_STRING;
575 uint32_t len = strlen(payload);
576
577 vec[0].iov_base = &tag;
578 vec[0].iov_len = sizeof(tag);
579 vec[1].iov_base = &type;
580 vec[1].iov_len = sizeof(type);
581 vec[2].iov_base = &len;
582 vec[2].iov_len = sizeof(len);
583 vec[3].iov_base = (void*)payload;
584 vec[3].iov_len = len;
585
586 return write_to_log(LOG_ID_EVENTS, vec, 4);
587}
588
589/*
590 * Like __android_log_security_bwrite, but used for writing strings to the
591 * security log.
592 */
593LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag,
594 const char *payload)
595{
596 struct iovec vec[4];
597 char type = EVENT_TYPE_STRING;
598 uint32_t len = strlen(payload);
599
600 vec[0].iov_base = &tag;
601 vec[0].iov_len = sizeof(tag);
602 vec[1].iov_base = &type;
603 vec[1].iov_len = sizeof(type);
604 vec[2].iov_base = &len;
605 vec[2].iov_len = sizeof(len);
606 vec[3].iov_base = (void*)payload;
607 vec[3].iov_len = len;
608
609 return write_to_log(LOG_ID_SECURITY, vec, 4);
610}