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