blob: 1e56b270b2858c096ab587e035be47a67008d7df [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;
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) {
298 m = android_openEventTagMap(EVENT_TAG_MAP_FILE);
299 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 }
356
357 clock_gettime(android_log_clockid(), &ts);
358#else
359 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
360 {
361 struct timeval tv;
362 gettimeofday(&tv, NULL);
363 ts.tv_sec = tv.tv_sec;
364 ts.tv_nsec = tv.tv_usec * 1000;
365 }
366#endif
367
368 ret = 0;
Mark Salyzync33103c2016-03-28 16:20:29 -0700369 i = 1 << log_id;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800370 write_transport_for_each(node, &__android_log_transport_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700371 if (node->logMask & i) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800372 ssize_t retval;
373 retval = (*node->write)(log_id, &ts, vec, nr);
374 if (ret >= 0) {
375 ret = retval;
376 }
377 }
378 }
379
380 write_transport_for_each(node, &__android_log_persist_write) {
Mark Salyzync33103c2016-03-28 16:20:29 -0700381 if (node->logMask & i) {
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800382 (void)(*node->write)(log_id, &ts, vec, nr);
383 }
384 }
385
386 return ret;
387}
388
389static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)
390{
391 __android_log_lock();
392
393 if (write_to_log == __write_to_log_init) {
394 int ret;
395
396 ret = __write_to_log_initialize();
397 if (ret < 0) {
398 __android_log_unlock();
399 if (!list_empty(&__android_log_persist_write)) {
400 __write_to_log_daemon(log_id, vec, nr);
401 }
402 return ret;
403 }
404
405 write_to_log = __write_to_log_daemon;
406 }
407
408 __android_log_unlock();
409
410 return write_to_log(log_id, vec, nr);
411}
412
413LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag,
414 const char *msg)
415{
416 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
417}
418
419LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
420 const char *tag, const char *msg)
421{
422 struct iovec vec[3];
423 char tmp_tag[32];
424
425 if (!tag)
426 tag = "";
427
428 /* XXX: This needs to go! */
429 if ((bufID != LOG_ID_RADIO) &&
430 (!strcmp(tag, "HTC_RIL") ||
431 !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
432 !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
433 !strcmp(tag, "AT") ||
434 !strcmp(tag, "GSM") ||
435 !strcmp(tag, "STK") ||
436 !strcmp(tag, "CDMA") ||
437 !strcmp(tag, "PHONE") ||
438 !strcmp(tag, "SMS"))) {
439 bufID = LOG_ID_RADIO;
440 /* Inform third party apps/ril/radio.. to use Rlog or RLOG */
441 snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
442 tag = tmp_tag;
443 }
444
445#if __BIONIC__
446 if (prio == ANDROID_LOG_FATAL) {
447 android_set_abort_message(msg);
448 }
449#endif
450
Mark Salyzync33103c2016-03-28 16:20:29 -0700451 vec[0].iov_base = (unsigned char *)&prio;
452 vec[0].iov_len = 1;
453 vec[1].iov_base = (void *)tag;
454 vec[1].iov_len = strlen(tag) + 1;
455 vec[2].iov_base = (void *)msg;
456 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800457
458 return write_to_log(bufID, vec, 3);
459}
460
461LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char *tag,
462 const char *fmt, va_list ap)
463{
464 char buf[LOG_BUF_SIZE];
465
466 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
467
468 return __android_log_write(prio, tag, buf);
469}
470
471LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char *tag,
472 const char *fmt, ...)
473{
474 va_list ap;
475 char buf[LOG_BUF_SIZE];
476
477 va_start(ap, fmt);
478 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
479 va_end(ap);
480
481 return __android_log_write(prio, tag, buf);
482}
483
484LIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio,
485 const char *tag,
486 const char *fmt, ...)
487{
488 va_list ap;
489 char buf[LOG_BUF_SIZE];
490
491 va_start(ap, fmt);
492 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
493 va_end(ap);
494
495 return __android_log_buf_write(bufID, prio, tag, buf);
496}
497
498LIBLOG_ABI_PUBLIC void __android_log_assert(const char *cond, const char *tag,
499 const char *fmt, ...)
500{
501 char buf[LOG_BUF_SIZE];
502
503 if (fmt) {
504 va_list ap;
505 va_start(ap, fmt);
506 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
507 va_end(ap);
508 } else {
509 /* Msg not provided, log condition. N.B. Do not use cond directly as
510 * format string as it could contain spurious '%' syntax (e.g.
511 * "%d" in "blocks%devs == 0").
512 */
513 if (cond)
514 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
515 else
516 strcpy(buf, "Unspecified assertion failed");
517 }
518
519 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
520 abort(); /* abort so we have a chance to debug the situation */
521 /* NOTREACHED */
522}
523
524LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag,
525 const void *payload, size_t len)
526{
527 struct iovec vec[2];
528
529 vec[0].iov_base = &tag;
530 vec[0].iov_len = sizeof(tag);
531 vec[1].iov_base = (void*)payload;
532 vec[1].iov_len = len;
533
534 return write_to_log(LOG_ID_EVENTS, vec, 2);
535}
536
537LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag,
538 const void *payload,
539 size_t len)
540{
541 struct iovec vec[2];
542
543 vec[0].iov_base = &tag;
544 vec[0].iov_len = sizeof(tag);
545 vec[1].iov_base = (void*)payload;
546 vec[1].iov_len = len;
547
548 return write_to_log(LOG_ID_SECURITY, vec, 2);
549}
550
551/*
552 * Like __android_log_bwrite, but takes the type as well. Doesn't work
553 * for the general case where we're generating lists of stuff, but very
554 * handy if we just want to dump an integer into the log.
555 */
556LIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type,
557 const void *payload, size_t len)
558{
559 struct iovec vec[3];
560
561 vec[0].iov_base = &tag;
562 vec[0].iov_len = sizeof(tag);
563 vec[1].iov_base = &type;
564 vec[1].iov_len = sizeof(type);
565 vec[2].iov_base = (void*)payload;
566 vec[2].iov_len = len;
567
568 return write_to_log(LOG_ID_EVENTS, vec, 3);
569}
570
571/*
572 * Like __android_log_bwrite, but used for writing strings to the
573 * event log.
574 */
575LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload)
576{
577 struct iovec vec[4];
578 char type = EVENT_TYPE_STRING;
579 uint32_t len = strlen(payload);
580
581 vec[0].iov_base = &tag;
582 vec[0].iov_len = sizeof(tag);
583 vec[1].iov_base = &type;
584 vec[1].iov_len = sizeof(type);
585 vec[2].iov_base = &len;
586 vec[2].iov_len = sizeof(len);
587 vec[3].iov_base = (void*)payload;
588 vec[3].iov_len = len;
589
590 return write_to_log(LOG_ID_EVENTS, vec, 4);
591}
592
593/*
594 * Like __android_log_security_bwrite, but used for writing strings to the
595 * security log.
596 */
597LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag,
598 const char *payload)
599{
600 struct iovec vec[4];
601 char type = EVENT_TYPE_STRING;
602 uint32_t len = strlen(payload);
603
604 vec[0].iov_base = &tag;
605 vec[0].iov_len = sizeof(tag);
606 vec[1].iov_base = &type;
607 vec[1].iov_len = sizeof(type);
608 vec[2].iov_base = &len;
609 vec[2].iov_len = sizeof(len);
610 vec[3].iov_base = (void*)payload;
611 vec[3].iov_len = len;
612
613 return write_to_log(LOG_ID_SECURITY, vec, 4);
614}