1 /*
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
40 static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);
41 static 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 */
48 static enum {
49 kLogUninitialized, kLogNotAvailable, kLogAvailable
50 } g_log_status = kLogUninitialized;
51
check_log_uid_permissions()52 static 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
__android_log_cache_available(struct android_log_transport_write * node)99 static 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
__android_log_dev_available()119 LIBLOG_ABI_PUBLIC int __android_log_dev_available()
120 {
121 struct android_log_transport_write *node;
122
123 if (list_empty(&__android_log_transport_write)) {
124 return kLogUninitialized;
125 }
126
127 write_transport_for_each(node, &__android_log_transport_write) {
128 __android_log_cache_available(node);
129 if (node->logMask) {
130 return kLogAvailable;
131 }
132 }
133 return kLogNotAvailable;
134 }
135
136 /* log_init_lock assumed */
__write_to_log_initialize()137 static int __write_to_log_initialize()
138 {
139 struct android_log_transport_write *transport;
140 struct listnode *n;
141 int i = 0, ret = 0;
142
143 __android_log_config_write();
144 write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
145 __android_log_cache_available(transport);
146 if (!transport->logMask) {
147 list_remove(&transport->node);
148 continue;
149 }
150 if (!transport->open || ((*transport->open)() < 0)) {
151 if (transport->close) {
152 (*transport->close)();
153 }
154 list_remove(&transport->node);
155 continue;
156 }
157 ++ret;
158 }
159 write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
160 __android_log_cache_available(transport);
161 if (!transport->logMask) {
162 list_remove(&transport->node);
163 continue;
164 }
165 if (!transport->open || ((*transport->open)() < 0)) {
166 if (transport->close) {
167 (*transport->close)();
168 }
169 list_remove(&transport->node);
170 continue;
171 }
172 ++i;
173 }
174 if (!ret && !i) {
175 return -ENODEV;
176 }
177
178 return ret;
179 }
180
181 /*
182 * Extract a 4-byte value from a byte stream. le32toh open coded
183 */
get4LE(const uint8_t * src)184 static inline uint32_t get4LE(const uint8_t* src)
185 {
186 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
187 }
188
__write_to_log_daemon(log_id_t log_id,struct iovec * vec,size_t nr)189 static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)
190 {
191 struct android_log_transport_write *node;
192 int ret;
193 struct timespec ts;
194 size_t len, i;
195
196 for (len = i = 0; i < nr; ++i) {
197 len += vec[i].iov_len;
198 }
199 if (!len) {
200 return -EINVAL;
201 }
202
203 #if defined(__BIONIC__)
204 if (log_id == LOG_ID_SECURITY) {
205 if (vec[0].iov_len < 4) {
206 return -EINVAL;
207 }
208
209 ret = check_log_uid_permissions();
210 if (ret < 0) {
211 return ret;
212 }
213 if (!__android_log_security()) {
214 /* If only we could reset downstream logd counter */
215 return -EPERM;
216 }
217 } else if (log_id == LOG_ID_EVENTS) {
218 static atomic_uintptr_t map;
219 const char *tag;
220 EventTagMap *m, *f;
221
222 if (vec[0].iov_len < 4) {
223 return -EINVAL;
224 }
225
226 tag = NULL;
227 f = NULL;
228 m = (EventTagMap *)atomic_load(&map);
229
230 if (!m) {
231 ret = __android_log_trylock();
232 m = (EventTagMap *)atomic_load(&map); /* trylock flush cache */
233 if (!m) {
234 m = android_openEventTagMap(EVENT_TAG_MAP_FILE);
235 if (ret) { /* trylock failed, use local copy, mark for close */
236 f = m;
237 } else {
238 if (!m) { /* One chance to open map file */
239 m = (EventTagMap *)(uintptr_t)-1LL;
240 }
241 atomic_store(&map, (uintptr_t)m);
242 }
243 }
244 if (!ret) { /* trylock succeeded, unlock */
245 __android_log_unlock();
246 }
247 }
248 if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) {
249 tag = android_lookupEventTag(m, get4LE(vec[0].iov_base));
250 }
251 ret = __android_log_is_loggable(ANDROID_LOG_INFO,
252 tag,
253 ANDROID_LOG_VERBOSE);
254 if (f) { /* local copy marked for close */
255 android_closeEventTagMap(f);
256 }
257 if (!ret) {
258 return -EPERM;
259 }
260 } else {
261 /* Validate the incoming tag, tag content can not split across iovec */
262 char prio = ANDROID_LOG_VERBOSE;
263 const char *tag = vec[0].iov_base;
264 size_t len = vec[0].iov_len;
265 if (!tag) {
266 len = 0;
267 }
268 if (len > 0) {
269 prio = *tag;
270 if (len > 1) {
271 --len;
272 ++tag;
273 } else {
274 len = vec[1].iov_len;
275 tag = ((const char *)vec[1].iov_base);
276 if (!tag) {
277 len = 0;
278 }
279 }
280 }
281 /* tag must be nul terminated */
282 if (strnlen(tag, len) >= len) {
283 tag = NULL;
284 }
285
286 if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
287 return -EPERM;
288 }
289 }
290
291 clock_gettime(android_log_clockid(), &ts);
292 #else
293 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
294 {
295 struct timeval tv;
296 gettimeofday(&tv, NULL);
297 ts.tv_sec = tv.tv_sec;
298 ts.tv_nsec = tv.tv_usec * 1000;
299 }
300 #endif
301
302 ret = 0;
303 i = 1 << log_id;
304 write_transport_for_each(node, &__android_log_transport_write) {
305 if (node->logMask & i) {
306 ssize_t retval;
307 retval = (*node->write)(log_id, &ts, vec, nr);
308 if (ret >= 0) {
309 ret = retval;
310 }
311 }
312 }
313
314 write_transport_for_each(node, &__android_log_persist_write) {
315 if (node->logMask & i) {
316 (void)(*node->write)(log_id, &ts, vec, nr);
317 }
318 }
319
320 return ret;
321 }
322
__write_to_log_init(log_id_t log_id,struct iovec * vec,size_t nr)323 static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)
324 {
325 __android_log_lock();
326
327 if (write_to_log == __write_to_log_init) {
328 int ret;
329
330 ret = __write_to_log_initialize();
331 if (ret < 0) {
332 __android_log_unlock();
333 if (!list_empty(&__android_log_persist_write)) {
334 __write_to_log_daemon(log_id, vec, nr);
335 }
336 return ret;
337 }
338
339 write_to_log = __write_to_log_daemon;
340 }
341
342 __android_log_unlock();
343
344 return write_to_log(log_id, vec, nr);
345 }
346
__android_log_write(int prio,const char * tag,const char * msg)347 LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag,
348 const char *msg)
349 {
350 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
351 }
352
__android_log_buf_write(int bufID,int prio,const char * tag,const char * msg)353 LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
354 const char *tag, const char *msg)
355 {
356 struct iovec vec[3];
357 char tmp_tag[32];
358
359 if (!tag)
360 tag = "";
361
362 /* XXX: This needs to go! */
363 if ((bufID != LOG_ID_RADIO) &&
364 (!strcmp(tag, "HTC_RIL") ||
365 !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
366 !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
367 !strcmp(tag, "AT") ||
368 !strcmp(tag, "GSM") ||
369 !strcmp(tag, "STK") ||
370 !strcmp(tag, "CDMA") ||
371 !strcmp(tag, "PHONE") ||
372 !strcmp(tag, "SMS"))) {
373 bufID = LOG_ID_RADIO;
374 /* Inform third party apps/ril/radio.. to use Rlog or RLOG */
375 snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
376 tag = tmp_tag;
377 }
378
379 #if __BIONIC__
380 if (prio == ANDROID_LOG_FATAL) {
381 android_set_abort_message(msg);
382 }
383 #endif
384
385 vec[0].iov_base = (unsigned char *)&prio;
386 vec[0].iov_len = 1;
387 vec[1].iov_base = (void *)tag;
388 vec[1].iov_len = strlen(tag) + 1;
389 vec[2].iov_base = (void *)msg;
390 vec[2].iov_len = strlen(msg) + 1;
391
392 return write_to_log(bufID, vec, 3);
393 }
394
__android_log_vprint(int prio,const char * tag,const char * fmt,va_list ap)395 LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char *tag,
396 const char *fmt, va_list ap)
397 {
398 char buf[LOG_BUF_SIZE];
399
400 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
401
402 return __android_log_write(prio, tag, buf);
403 }
404
__android_log_print(int prio,const char * tag,const char * fmt,...)405 LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char *tag,
406 const char *fmt, ...)
407 {
408 va_list ap;
409 char buf[LOG_BUF_SIZE];
410
411 va_start(ap, fmt);
412 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
413 va_end(ap);
414
415 return __android_log_write(prio, tag, buf);
416 }
417
__android_log_buf_print(int bufID,int prio,const char * tag,const char * fmt,...)418 LIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio,
419 const char *tag,
420 const char *fmt, ...)
421 {
422 va_list ap;
423 char buf[LOG_BUF_SIZE];
424
425 va_start(ap, fmt);
426 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
427 va_end(ap);
428
429 return __android_log_buf_write(bufID, prio, tag, buf);
430 }
431
__android_log_assert(const char * cond,const char * tag,const char * fmt,...)432 LIBLOG_ABI_PUBLIC void __android_log_assert(const char *cond, const char *tag,
433 const char *fmt, ...)
434 {
435 char buf[LOG_BUF_SIZE];
436
437 if (fmt) {
438 va_list ap;
439 va_start(ap, fmt);
440 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
441 va_end(ap);
442 } else {
443 /* Msg not provided, log condition. N.B. Do not use cond directly as
444 * format string as it could contain spurious '%' syntax (e.g.
445 * "%d" in "blocks%devs == 0").
446 */
447 if (cond)
448 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
449 else
450 strcpy(buf, "Unspecified assertion failed");
451 }
452
453 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
454 abort(); /* abort so we have a chance to debug the situation */
455 /* NOTREACHED */
456 }
457
__android_log_bwrite(int32_t tag,const void * payload,size_t len)458 LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag,
459 const void *payload, size_t len)
460 {
461 struct iovec vec[2];
462
463 vec[0].iov_base = &tag;
464 vec[0].iov_len = sizeof(tag);
465 vec[1].iov_base = (void*)payload;
466 vec[1].iov_len = len;
467
468 return write_to_log(LOG_ID_EVENTS, vec, 2);
469 }
470
__android_log_security_bwrite(int32_t tag,const void * payload,size_t len)471 LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag,
472 const void *payload,
473 size_t len)
474 {
475 struct iovec vec[2];
476
477 vec[0].iov_base = &tag;
478 vec[0].iov_len = sizeof(tag);
479 vec[1].iov_base = (void*)payload;
480 vec[1].iov_len = len;
481
482 return write_to_log(LOG_ID_SECURITY, vec, 2);
483 }
484
485 /*
486 * Like __android_log_bwrite, but takes the type as well. Doesn't work
487 * for the general case where we're generating lists of stuff, but very
488 * handy if we just want to dump an integer into the log.
489 */
__android_log_btwrite(int32_t tag,char type,const void * payload,size_t len)490 LIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type,
491 const void *payload, size_t len)
492 {
493 struct iovec vec[3];
494
495 vec[0].iov_base = &tag;
496 vec[0].iov_len = sizeof(tag);
497 vec[1].iov_base = &type;
498 vec[1].iov_len = sizeof(type);
499 vec[2].iov_base = (void*)payload;
500 vec[2].iov_len = len;
501
502 return write_to_log(LOG_ID_EVENTS, vec, 3);
503 }
504
505 /*
506 * Like __android_log_bwrite, but used for writing strings to the
507 * event log.
508 */
__android_log_bswrite(int32_t tag,const char * payload)509 LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload)
510 {
511 struct iovec vec[4];
512 char type = EVENT_TYPE_STRING;
513 uint32_t len = strlen(payload);
514
515 vec[0].iov_base = &tag;
516 vec[0].iov_len = sizeof(tag);
517 vec[1].iov_base = &type;
518 vec[1].iov_len = sizeof(type);
519 vec[2].iov_base = &len;
520 vec[2].iov_len = sizeof(len);
521 vec[3].iov_base = (void*)payload;
522 vec[3].iov_len = len;
523
524 return write_to_log(LOG_ID_EVENTS, vec, 4);
525 }
526
527 /*
528 * Like __android_log_security_bwrite, but used for writing strings to the
529 * security log.
530 */
__android_log_security_bswrite(int32_t tag,const char * payload)531 LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag,
532 const char *payload)
533 {
534 struct iovec vec[4];
535 char type = EVENT_TYPE_STRING;
536 uint32_t len = strlen(payload);
537
538 vec[0].iov_base = &tag;
539 vec[0].iov_len = sizeof(tag);
540 vec[1].iov_base = &type;
541 vec[1].iov_len = sizeof(type);
542 vec[2].iov_base = &len;
543 vec[2].iov_len = sizeof(len);
544 vec[3].iov_base = (void*)payload;
545 vec[3].iov_len = len;
546
547 return write_to_log(LOG_ID_SECURITY, vec, 4);
548 }
549