blob: 43241254faad81f017e646b26cf0d4c428417060 [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
27#include <log/event_tag_map.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080028#include <private/android_filesystem_config.h>
29#include <private/android_logger.h>
30
31#include "config_write.h"
32#include "log_portability.h"
33#include "logger.h"
34
35#define LOG_BUF_SIZE 1024
36
37static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);
38static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;
39
40/*
41 * This is used by the C++ code to decide if it should write logs through
42 * the C code. Basically, if /dev/socket/logd is available, we're running in
43 * the simulator rather than a desktop tool and want to use the device.
44 */
45static enum {
46 kLogUninitialized, kLogNotAvailable, kLogAvailable
47} g_log_status = kLogUninitialized;
48
Mark Salyzync33103c2016-03-28 16:20:29 -070049static int check_log_uid_permissions()
50{
Dan Willemsen0910d2d2016-11-29 13:39:55 -080051#if defined(__ANDROID__)
Mark Salyzync33103c2016-03-28 16:20:29 -070052 uid_t uid = __android_log_uid();
53
54 /* Matches clientHasLogCredentials() in logd */
55 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
56 uid = geteuid();
57 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
58 gid_t gid = getgid();
59 if ((gid != AID_SYSTEM) &&
60 (gid != AID_ROOT) &&
61 (gid != AID_LOG)) {
62 gid = getegid();
63 if ((gid != AID_SYSTEM) &&
64 (gid != AID_ROOT) &&
65 (gid != AID_LOG)) {
66 int num_groups;
67 gid_t *groups;
68
69 num_groups = getgroups(0, NULL);
70 if (num_groups <= 0) {
71 return -EPERM;
72 }
73 groups = calloc(num_groups, sizeof(gid_t));
74 if (!groups) {
75 return -ENOMEM;
76 }
77 num_groups = getgroups(num_groups, groups);
78 while (num_groups > 0) {
79 if (groups[num_groups - 1] == AID_LOG) {
80 break;
81 }
82 --num_groups;
83 }
84 free(groups);
85 if (num_groups <= 0) {
86 return -EPERM;
87 }
88 }
89 }
90 }
91 }
92#endif
93 return 0;
94}
95
96static void __android_log_cache_available(
97 struct android_log_transport_write *node)
98{
99 size_t i;
100
101 if (node->logMask) {
102 return;
103 }
104
105 for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
106 if (node->write &&
107 (i != LOG_ID_KERNEL) &&
108 ((i != LOG_ID_SECURITY) ||
109 (check_log_uid_permissions() == 0)) &&
110 (!node->available || ((*node->available)(i) >= 0))) {
111 node->logMask |= 1 << i;
112 }
113 }
114}
115
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800116LIBLOG_ABI_PUBLIC int __android_log_dev_available()
117{
118 struct android_log_transport_write *node;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800119
120 if (list_empty(&__android_log_transport_write)) {
121 return kLogUninitialized;
122 }
Mark Salyzync33103c2016-03-28 16:20:29 -0700123
124 write_transport_for_each(node, &__android_log_transport_write) {
125 __android_log_cache_available(node);
126 if (node->logMask) {
127 return kLogAvailable;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800128 }
129 }
130 return kLogNotAvailable;
131}
Mark Salyzynba1a7982016-09-13 07:28:21 -0700132
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800133#if defined(__ANDROID__)
Mark Salyzynba1a7982016-09-13 07:28:21 -0700134static atomic_uintptr_t tagMap;
135#endif
136
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700137/*
138 * Release any logger resources. A new log write will immediately re-acquire.
139 */
140LIBLOG_ABI_PUBLIC void __android_log_close()
141{
142 struct android_log_transport_write *transport;
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800143#if defined(__ANDROID__)
Mark Salyzynba1a7982016-09-13 07:28:21 -0700144 EventTagMap *m;
145#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700146
147 __android_log_lock();
148
149 write_to_log = __write_to_log_init;
150
151 /*
152 * Threads that are actively writing at this point are not held back
153 * by a lock and are at risk of dropping the messages with a return code
154 * -EBADF. Prefer to return error code than add the overhead of a lock to
155 * each log writing call to guarantee delivery. In addition, anyone
156 * calling this is doing so to release the logging resources and shut down,
157 * for them to do so with outstanding log requests in other threads is a
158 * disengenuous use of this function.
159 */
160
161 write_transport_for_each(transport, &__android_log_persist_write) {
162 if (transport->close) {
163 (*transport->close)();
164 }
165 }
166
167 write_transport_for_each(transport, &__android_log_transport_write) {
168 if (transport->close) {
169 (*transport->close)();
170 }
171 }
172
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800173#if defined(__ANDROID__)
Mark Salyzynba1a7982016-09-13 07:28:21 -0700174 /*
175 * Additional risk here somewhat mitigated by immediately unlock flushing
176 * the processor cache. The multi-threaded race that we choose to accept,
177 * to minimize locking, is an atomic_load in a writer picking up a value
178 * just prior to entering this routine. There will be an use after free.
179 *
180 * Again, anyone calling this is doing so to release the logging resources
181 * is most probably going to quiesce then shut down; or to restart after
182 * a fork so the risk should be non-existent. For this reason we
183 * choose a mitigation stance for efficiency instead of incuring the cost
184 * of a lock for every log write.
185 */
186 m = (EventTagMap *)atomic_exchange(&tagMap, (uintptr_t)0);
187#endif
188
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700189 __android_log_unlock();
Mark Salyzynba1a7982016-09-13 07:28:21 -0700190
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800191#if defined(__ANDROID__)
Mark Salyzyn53e9fc72016-11-09 10:14:35 -0800192 if (m != (EventTagMap *)(uintptr_t)-1LL) android_closeEventTagMap(m);
Mark Salyzynba1a7982016-09-13 07:28:21 -0700193#endif
194
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700195}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800196
197/* log_init_lock assumed */
198static int __write_to_log_initialize()
199{
200 struct android_log_transport_write *transport;
201 struct listnode *n;
202 int i = 0, ret = 0;
203
204 __android_log_config_write();
205 write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700206 __android_log_cache_available(transport);
207 if (!transport->logMask) {
208 list_remove(&transport->node);
209 continue;
210 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800211 if (!transport->open || ((*transport->open)() < 0)) {
212 if (transport->close) {
213 (*transport->close)();
214 }
215 list_remove(&transport->node);
216 continue;
217 }
218 ++ret;
219 }
220 write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700221 __android_log_cache_available(transport);
222 if (!transport->logMask) {
223 list_remove(&transport->node);
224 continue;
225 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800226 if (!transport->open || ((*transport->open)() < 0)) {
227 if (transport->close) {
228 (*transport->close)();
229 }
230 list_remove(&transport->node);
231 continue;
232 }
233 ++i;
234 }
235 if (!ret && !i) {
236 return -ENODEV;
237 }
238
239 return ret;
240}
241
242/*
243 * Extract a 4-byte value from a byte stream. le32toh open coded
244 */
245static inline uint32_t get4LE(const uint8_t* src)
246{
247 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
248}
249
250static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
251{
252 struct android_log_transport_write *node;
253 int ret;
254 struct timespec ts;
255 size_t len, i;
256
257 for (len = i = 0; i < nr; ++i) {
258 len += vec[i].iov_len;
259 }
260 if (!len) {
261 return -EINVAL;
262 }
263
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800264#if defined(__ANDROID__)
Mark Salyzyn142b43d2016-12-28 10:30:57 -0800265 clock_gettime(android_log_clockid(), &ts);
266
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800267 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;
Mark Salyzyn807e40e2016-09-22 09:56:51 -0700282 size_t len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800283 EventTagMap *m, *f;
284
285 if (vec[0].iov_len < 4) {
286 return -EINVAL;
287 }
288
289 tag = NULL;
Mark Salyzyn807e40e2016-09-22 09:56:51 -0700290 len = 0;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800291 f = NULL;
Mark Salyzynba1a7982016-09-13 07:28:21 -0700292 m = (EventTagMap *)atomic_load(&tagMap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800293
294 if (!m) {
295 ret = __android_log_trylock();
Mark Salyzynba1a7982016-09-13 07:28:21 -0700296 m = (EventTagMap *)atomic_load(&tagMap); /* trylock flush cache */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800297 if (!m) {
Mark Salyzyn1179eb82016-11-11 09:48:56 -0800298 m = android_openEventTagMap(NULL);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800299 if (ret) { /* trylock failed, use local copy, mark for close */
300 f = m;
301 } else {
302 if (!m) { /* One chance to open map file */
303 m = (EventTagMap *)(uintptr_t)-1LL;
304 }
Mark Salyzynba1a7982016-09-13 07:28:21 -0700305 atomic_store(&tagMap, (uintptr_t)m);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800306 }
307 }
308 if (!ret) { /* trylock succeeded, unlock */
309 __android_log_unlock();
310 }
311 }
312 if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) {
Mark Salyzyn807e40e2016-09-22 09:56:51 -0700313 tag = android_lookupEventTag_len(m, &len, get4LE(vec[0].iov_base));
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800314 }
Mark Salyzyn807e40e2016-09-22 09:56:51 -0700315 ret = __android_log_is_loggable_len(ANDROID_LOG_INFO,
316 tag, len,
317 ANDROID_LOG_VERBOSE);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800318 if (f) { /* local copy marked for close */
319 android_closeEventTagMap(f);
320 }
321 if (!ret) {
322 return -EPERM;
323 }
324 } else {
325 /* Validate the incoming tag, tag content can not split across iovec */
326 char prio = ANDROID_LOG_VERBOSE;
327 const char *tag = vec[0].iov_base;
328 size_t len = vec[0].iov_len;
329 if (!tag) {
330 len = 0;
331 }
332 if (len > 0) {
333 prio = *tag;
334 if (len > 1) {
335 --len;
336 ++tag;
337 } else {
338 len = vec[1].iov_len;
339 tag = ((const char *)vec[1].iov_base);
340 if (!tag) {
341 len = 0;
342 }
343 }
344 }
345 /* tag must be nul terminated */
346 if (strnlen(tag, len) >= len) {
347 tag = NULL;
348 }
349
Mark Salyzyn807e40e2016-09-22 09:56:51 -0700350 if (!__android_log_is_loggable_len(prio,
351 tag, len - 1,
352 ANDROID_LOG_VERBOSE)) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800353 return -EPERM;
354 }
355 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800356#else
357 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
358 {
359 struct timeval tv;
360 gettimeofday(&tv, NULL);
361 ts.tv_sec = tv.tv_sec;
362 ts.tv_nsec = tv.tv_usec * 1000;
363 }
364#endif
365
366 ret = 0;
Mark Salyzync33103c2016-03-28 16:20:29 -0700367 i = 1 << log_id;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800368 write_transport_for_each(node, &__android_log_transport_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700369 if (node->logMask & i) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800370 ssize_t retval;
371 retval = (*node->write)(log_id, &ts, vec, nr);
372 if (ret >= 0) {
373 ret = retval;
374 }
375 }
376 }
377
378 write_transport_for_each(node, &__android_log_persist_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700379 if (node->logMask & i) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800380 (void)(*node->write)(log_id, &ts, vec, nr);
381 }
382 }
383
384 return ret;
385}
386
387static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)
388{
389 __android_log_lock();
390
391 if (write_to_log == __write_to_log_init) {
392 int ret;
393
394 ret = __write_to_log_initialize();
395 if (ret < 0) {
396 __android_log_unlock();
397 if (!list_empty(&__android_log_persist_write)) {
398 __write_to_log_daemon(log_id, vec, nr);
399 }
400 return ret;
401 }
402
403 write_to_log = __write_to_log_daemon;
404 }
405
406 __android_log_unlock();
407
408 return write_to_log(log_id, vec, nr);
409}
410
411LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag,
412 const char *msg)
413{
414 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
415}
416
417LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
418 const char *tag, const char *msg)
419{
420 struct iovec vec[3];
421 char tmp_tag[32];
422
423 if (!tag)
424 tag = "";
425
426 /* XXX: This needs to go! */
427 if ((bufID != LOG_ID_RADIO) &&
428 (!strcmp(tag, "HTC_RIL") ||
429 !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
430 !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
431 !strcmp(tag, "AT") ||
432 !strcmp(tag, "GSM") ||
433 !strcmp(tag, "STK") ||
434 !strcmp(tag, "CDMA") ||
435 !strcmp(tag, "PHONE") ||
436 !strcmp(tag, "SMS"))) {
437 bufID = LOG_ID_RADIO;
438 /* Inform third party apps/ril/radio.. to use Rlog or RLOG */
439 snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
440 tag = tmp_tag;
441 }
442
443#if __BIONIC__
444 if (prio == ANDROID_LOG_FATAL) {
445 android_set_abort_message(msg);
446 }
447#endif
448
Mark Salyzync33103c2016-03-28 16:20:29 -0700449 vec[0].iov_base = (unsigned char *)&prio;
450 vec[0].iov_len = 1;
451 vec[1].iov_base = (void *)tag;
452 vec[1].iov_len = strlen(tag) + 1;
453 vec[2].iov_base = (void *)msg;
454 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800455
456 return write_to_log(bufID, vec, 3);
457}
458
459LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char *tag,
460 const char *fmt, va_list ap)
461{
462 char buf[LOG_BUF_SIZE];
463
464 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
465
466 return __android_log_write(prio, tag, buf);
467}
468
469LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char *tag,
470 const char *fmt, ...)
471{
472 va_list ap;
473 char buf[LOG_BUF_SIZE];
474
475 va_start(ap, fmt);
476 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
477 va_end(ap);
478
479 return __android_log_write(prio, tag, buf);
480}
481
482LIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio,
483 const char *tag,
484 const char *fmt, ...)
485{
486 va_list ap;
487 char buf[LOG_BUF_SIZE];
488
489 va_start(ap, fmt);
490 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
491 va_end(ap);
492
493 return __android_log_buf_write(bufID, prio, tag, buf);
494}
495
496LIBLOG_ABI_PUBLIC void __android_log_assert(const char *cond, const char *tag,
497 const char *fmt, ...)
498{
499 char buf[LOG_BUF_SIZE];
500
501 if (fmt) {
502 va_list ap;
503 va_start(ap, fmt);
504 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
505 va_end(ap);
506 } else {
507 /* Msg not provided, log condition. N.B. Do not use cond directly as
508 * format string as it could contain spurious '%' syntax (e.g.
509 * "%d" in "blocks%devs == 0").
510 */
511 if (cond)
512 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
513 else
514 strcpy(buf, "Unspecified assertion failed");
515 }
516
Elliott Hughes5bae1b82017-02-06 10:54:00 -0800517 // Log assertion failures to stderr for the benefit of "adb shell" users
518 // and gtests (http://b/23675822).
519 struct iovec iov[2] = {
520 { buf, strlen(buf) },
521 { (char*) "\n", 1 },
522 };
523 TEMP_FAILURE_RETRY(writev(2, iov, 2));
524
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800525 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
526 abort(); /* abort so we have a chance to debug the situation */
527 /* NOTREACHED */
528}
529
530LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag,
531 const void *payload, size_t len)
532{
533 struct iovec vec[2];
534
535 vec[0].iov_base = &tag;
536 vec[0].iov_len = sizeof(tag);
537 vec[1].iov_base = (void*)payload;
538 vec[1].iov_len = len;
539
540 return write_to_log(LOG_ID_EVENTS, vec, 2);
541}
542
543LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag,
544 const void *payload,
545 size_t len)
546{
547 struct iovec vec[2];
548
549 vec[0].iov_base = &tag;
550 vec[0].iov_len = sizeof(tag);
551 vec[1].iov_base = (void*)payload;
552 vec[1].iov_len = len;
553
554 return write_to_log(LOG_ID_SECURITY, vec, 2);
555}
556
557/*
558 * Like __android_log_bwrite, but takes the type as well. Doesn't work
559 * for the general case where we're generating lists of stuff, but very
560 * handy if we just want to dump an integer into the log.
561 */
562LIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type,
563 const void *payload, size_t len)
564{
565 struct iovec vec[3];
566
567 vec[0].iov_base = &tag;
568 vec[0].iov_len = sizeof(tag);
569 vec[1].iov_base = &type;
570 vec[1].iov_len = sizeof(type);
571 vec[2].iov_base = (void*)payload;
572 vec[2].iov_len = len;
573
574 return write_to_log(LOG_ID_EVENTS, vec, 3);
575}
576
577/*
578 * Like __android_log_bwrite, but used for writing strings to the
579 * event log.
580 */
581LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload)
582{
583 struct iovec vec[4];
584 char type = EVENT_TYPE_STRING;
585 uint32_t len = strlen(payload);
586
587 vec[0].iov_base = &tag;
588 vec[0].iov_len = sizeof(tag);
589 vec[1].iov_base = &type;
590 vec[1].iov_len = sizeof(type);
591 vec[2].iov_base = &len;
592 vec[2].iov_len = sizeof(len);
593 vec[3].iov_base = (void*)payload;
594 vec[3].iov_len = len;
595
596 return write_to_log(LOG_ID_EVENTS, vec, 4);
597}
598
599/*
600 * Like __android_log_security_bwrite, but used for writing strings to the
601 * security log.
602 */
603LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag,
604 const char *payload)
605{
606 struct iovec vec[4];
607 char type = EVENT_TYPE_STRING;
608 uint32_t len = strlen(payload);
609
610 vec[0].iov_base = &tag;
611 vec[0].iov_len = sizeof(tag);
612 vec[1].iov_base = &type;
613 vec[1].iov_len = sizeof(type);
614 vec[2].iov_base = &len;
615 vec[2].iov_len = sizeof(len);
616 vec[3].iov_base = (void*)payload;
617 vec[3].iov_len = len;
618
619 return write_to_log(LOG_ID_SECURITY, vec, 4);
620}