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