• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define _POSIX_THREAD_SAFE_FUNCTIONS  // For mingw localtime_r().
18 
19 #include "logger_write.h"
20 
21 #include <errno.h>
22 #include <inttypes.h>
23 #include <libgen.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/time.h>
27 
28 #ifdef __BIONIC__
29 #include <android/set_abort_message.h>
30 #endif
31 
32 #include <atomic>
33 
34 #include <android-base/errno_restorer.h>
35 #include <android-base/macros.h>
36 #include <private/android_filesystem_config.h>
37 #include <private/android_logger.h>
38 
39 #include "android/log.h"
40 #include "log/log_read.h"
41 #include "logger.h"
42 #include "uio.h"
43 
44 #ifdef __ANDROID__
45 #include "logd_writer.h"
46 #include "pmsg_writer.h"
47 #endif
48 
49 #if defined(__APPLE__)
50 #include <pthread.h>
51 #elif defined(__linux__) && !defined(__ANDROID__)
52 #include <syscall.h>
53 #elif defined(_WIN32)
54 #include <windows.h>
55 #endif
56 
57 // The preferred way to access system properties is using android::base::GetProperty in libbase.
58 // However, adding dependency to libbase requires that if liblog was statically linked to a client,
59 // that client now has additional dependency to libbase as well because static dependencies of
60 // static library is not exported. (users of liblog.so however is fine).
61 #ifdef __ANDROID__
62 #include <sys/system_properties.h>
63 #endif
64 
65 using android::base::ErrnoRestorer;
66 
67 #define LOG_BUF_SIZE 1024
68 
69 #if defined(__ANDROID__)
check_log_uid_permissions()70 static int check_log_uid_permissions() {
71   uid_t uid = getuid();
72 
73   /* Matches clientCanWriteSecurityLog() in logd */
74   if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
75     uid = geteuid();
76     if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
77       gid_t gid = getgid();
78       if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
79         gid = getegid();
80         if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
81           int num_groups;
82           gid_t* groups;
83 
84           num_groups = getgroups(0, NULL);
85           if (num_groups <= 0) {
86             return -EPERM;
87           }
88           groups = static_cast<gid_t*>(calloc(num_groups, sizeof(gid_t)));
89           if (!groups) {
90             return -ENOMEM;
91           }
92           num_groups = getgroups(num_groups, groups);
93           while (num_groups > 0) {
94             if (groups[num_groups - 1] == AID_LOG ||
95                 groups[num_groups - 1] == AID_SECURITY_LOG_WRITER) {
96               break;
97             }
98             --num_groups;
99           }
100           free(groups);
101           if (num_groups <= 0) {
102             return -EPERM;
103           }
104         }
105       }
106     }
107   }
108   return 0;
109 }
110 #endif
111 
112 /*
113  * Release any logger resources. A new log write will immediately re-acquire.
114  */
__android_log_close()115 void __android_log_close() {
116 #ifdef __ANDROID__
117   LogdClose();
118   PmsgClose();
119 #endif
120 }
121 
122 // BSD-based systems like Android/macOS have getprogname(). Others need us to provide one.
123 #if !defined(__APPLE__) && !defined(__BIONIC__)
getprogname()124 static const char* getprogname() {
125 #ifdef _WIN32
126   static bool first = true;
127   static char progname[MAX_PATH] = {};
128 
129   if (first) {
130     char path[PATH_MAX + 1];
131     DWORD result = GetModuleFileName(nullptr, path, sizeof(path) - 1);
132     if (result == 0 || result == sizeof(path) - 1) return "";
133     path[PATH_MAX - 1] = 0;
134 
135     char* path_basename = basename(path);
136 
137     snprintf(progname, sizeof(progname), "%s", path_basename);
138     first = false;
139   }
140 
141   return progname;
142 #else
143   return program_invocation_short_name;
144 #endif
145 }
146 #endif
147 
148 // It's possible for logging to happen during static initialization before our globals are
149 // initialized, so we place this std::string in a function such that it is initialized on the first
150 // call. We use a pointer to avoid exit time destructors.
GetDefaultTag()151 std::string& GetDefaultTag() {
152   static std::string* default_tag = new std::string(getprogname());
153   return *default_tag;
154 }
155 
__android_log_set_default_tag(const char * tag)156 void __android_log_set_default_tag(const char* tag) {
157   GetDefaultTag().assign(tag, 0, LOGGER_ENTRY_MAX_PAYLOAD);
158 }
159 
160 static std::atomic_int32_t minimum_log_priority = ANDROID_LOG_DEFAULT;
__android_log_set_minimum_priority(int32_t priority)161 int32_t __android_log_set_minimum_priority(int32_t priority) {
162   return minimum_log_priority.exchange(priority, std::memory_order_relaxed);
163 }
164 
__android_log_get_minimum_priority()165 int32_t __android_log_get_minimum_priority() {
166   return minimum_log_priority;
167 }
168 
169 #ifdef __ANDROID__
170 static __android_logger_function logger_function = __android_log_logd_logger;
171 #else
172 static __android_logger_function logger_function = __android_log_stderr_logger;
173 #endif
174 
__android_log_set_logger(__android_logger_function logger)175 void __android_log_set_logger(__android_logger_function logger) {
176   logger_function = logger;
177 }
178 
__android_log_default_aborter(const char * abort_message)179 void __android_log_default_aborter(const char* abort_message) {
180 #ifdef __ANDROID__
181   android_set_abort_message(abort_message);
182 #else
183   UNUSED(abort_message);
184 #endif
185   abort();
186 }
187 
188 static __android_aborter_function aborter_function = __android_log_default_aborter;
189 
__android_log_set_aborter(__android_aborter_function aborter)190 void __android_log_set_aborter(__android_aborter_function aborter) {
191   aborter_function = aborter;
192 }
193 
__android_log_call_aborter(const char * abort_message)194 void __android_log_call_aborter(const char* abort_message) {
195   aborter_function(abort_message);
196 }
197 
198 #ifdef __ANDROID__
write_to_log(log_id_t log_id,struct iovec * vec,size_t nr)199 static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr) {
200   int ret;
201   struct timespec ts;
202 
203   if (log_id == LOG_ID_KERNEL) {
204     return -EINVAL;
205   }
206 
207   clock_gettime(CLOCK_REALTIME, &ts);
208 
209   if (log_id == LOG_ID_SECURITY) {
210     if (vec[0].iov_len < 4) {
211       return -EINVAL;
212     }
213 
214     ret = check_log_uid_permissions();
215     if (ret < 0) {
216       return ret;
217     }
218     if (!__android_log_security()) {
219       /* If only we could reset downstream logd counter */
220       return -EPERM;
221     }
222   } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
223     if (vec[0].iov_len < 4) {
224       return -EINVAL;
225     }
226   }
227 
228   ret = LogdWrite(log_id, &ts, vec, nr);
229   PmsgWrite(log_id, &ts, vec, nr);
230 
231   return ret;
232 }
233 #else
write_to_log(log_id_t,struct iovec *,size_t)234 static int write_to_log(log_id_t, struct iovec*, size_t) {
235   // Non-Android text logs should go to __android_log_stderr_logger, not here.
236   // Non-Android binary logs are always dropped.
237   return 1;
238 }
239 #endif
240 
241 // Copied from base/threads.cpp
GetThreadId()242 static uint64_t GetThreadId() {
243 #if defined(__BIONIC__)
244   return gettid();
245 #elif defined(__APPLE__)
246   uint64_t tid;
247   pthread_threadid_np(NULL, &tid);
248   return tid;
249 #elif defined(__linux__)
250   return syscall(__NR_gettid);
251 #elif defined(_WIN32)
252   return GetCurrentThreadId();
253 #endif
254 }
255 
filestream_logger(const struct __android_log_message * log_message,FILE * stream)256 static void filestream_logger(const struct __android_log_message* log_message, FILE* stream) {
257   struct timespec ts;
258   clock_gettime(CLOCK_REALTIME, &ts);
259 
260   struct tm now;
261   localtime_r(&ts.tv_sec, &now);
262 
263   char timestamp[sizeof("mm-DD HH::MM::SS.mmm\0")];
264   size_t n = strftime(timestamp, sizeof(timestamp), "%m-%d %H:%M:%S", &now);
265   snprintf(timestamp + n, sizeof(timestamp) - n, ".%03ld", ts.tv_nsec / (1000 * 1000));
266 
267   static const char log_characters[] = "XXVDIWEF";
268   static_assert(arraysize(log_characters) - 1 == ANDROID_LOG_SILENT,
269                 "Mismatch in size of log_characters and values in android_LogPriority");
270   int32_t priority =
271       log_message->priority > ANDROID_LOG_SILENT ? ANDROID_LOG_FATAL : log_message->priority;
272   char priority_char = log_characters[priority];
273   uint64_t tid = GetThreadId();
274   const char* tag = log_message->tag ? log_message->tag : " nullptr";
275 
276   if (log_message->file != nullptr) {
277     fprintf(stream, "%s %5d %5" PRIu64 " %c %-8s: %s:%u %s\n", timestamp, getpid(), tid,
278             priority_char, tag, log_message->file, log_message->line, log_message->message);
279   } else {
280     fprintf(stream, "%s %5d %5" PRIu64 " %c %-8s: %s\n", timestamp, getpid(), tid, priority_char,
281             tag, log_message->message);
282   }
283 }
284 
get_file_logger_path()285 static const char* get_file_logger_path() {
286 #ifdef __ANDROID__
287   static const char* file_logger_path = []() {
288     static char path[PROP_VALUE_MAX] = {};
289     if (__system_property_get("ro.log.file_logger.path", path) > 0) {
290       return path;
291     }
292     return static_cast<char*>(nullptr);  // means file_logger should not be used
293   }();
294   return file_logger_path;
295 #else
296   return nullptr;
297 #endif
298 }
299 
300 /*
301  * If ro.log.file_logger.path is set to a file, send log_message to the file instead. This is for
302  * Android-like environments where logd is not available; e.g. Microdroid. If the file is not
303  * accessible (but ro.log.file_logger.path is set anyway), stderr is chosen as the fallback.
304  *
305  * Returns true if log was sent to file. false, if not.
306  */
log_to_file_if_overridden(const struct __android_log_message * log_message)307 static bool log_to_file_if_overridden(const struct __android_log_message* log_message) {
308   const char* file_logger_path = get_file_logger_path();
309   if (file_logger_path == nullptr) return false;
310 
311   static FILE* stream = [&file_logger_path]() {
312     FILE* f = fopen(file_logger_path, "ae");
313     if (f != nullptr) return f;
314     using namespace std::string_literals;
315     std::string err_msg = "Cannot open "s + file_logger_path + " for logging: (" + strerror(errno) +
316                           "). Falling back to stderr";
317     __android_log_message m = {sizeof(__android_log_message),
318                                LOG_ID_DEFAULT,
319                                ANDROID_LOG_WARN,
320                                "liblog",
321                                __FILE__,
322                                __LINE__,
323                                err_msg.c_str()};
324     filestream_logger(&m, stderr);
325     return stderr;
326   }();
327   filestream_logger(log_message, stream);
328   return true;
329 }
330 
__android_log_stderr_logger(const struct __android_log_message * log_message)331 void __android_log_stderr_logger(const struct __android_log_message* log_message) {
332   filestream_logger(log_message, stderr);
333 }
334 
__android_log_logd_logger(const struct __android_log_message * log_message)335 void __android_log_logd_logger(const struct __android_log_message* log_message) {
336   if (log_to_file_if_overridden(log_message)) return;
337 
338   int buffer_id = log_message->buffer_id == LOG_ID_DEFAULT ? LOG_ID_MAIN : log_message->buffer_id;
339 
340   struct iovec vec[3];
341   vec[0].iov_base =
342       const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(&log_message->priority));
343   vec[0].iov_len = 1;
344   vec[1].iov_base = const_cast<void*>(static_cast<const void*>(log_message->tag));
345   vec[1].iov_len = strlen(log_message->tag) + 1;
346   vec[2].iov_base = const_cast<void*>(static_cast<const void*>(log_message->message));
347   vec[2].iov_len = strlen(log_message->message) + 1;
348 
349   write_to_log(static_cast<log_id_t>(buffer_id), vec, 3);
350 }
351 
__android_log_write(int prio,const char * tag,const char * msg)352 int __android_log_write(int prio, const char* tag, const char* msg) {
353   return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
354 }
355 
__android_log_write_log_message(__android_log_message * log_message)356 void __android_log_write_log_message(__android_log_message* log_message) {
357   ErrnoRestorer errno_restorer;
358 
359   if (log_message->buffer_id != LOG_ID_DEFAULT && log_message->buffer_id != LOG_ID_MAIN &&
360       log_message->buffer_id != LOG_ID_SYSTEM && log_message->buffer_id != LOG_ID_RADIO &&
361       log_message->buffer_id != LOG_ID_CRASH) {
362     return;
363   }
364 
365   if (log_message->tag == nullptr) {
366     log_message->tag = GetDefaultTag().c_str();
367   }
368 
369 #if __BIONIC__
370   if (log_message->priority == ANDROID_LOG_FATAL) {
371     android_set_abort_message(log_message->message);
372   }
373 #endif
374 
375   logger_function(log_message);
376 }
377 
__android_log_buf_write(int bufID,int prio,const char * tag,const char * msg)378 int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
379   ErrnoRestorer errno_restorer;
380 
381   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
382     return -EPERM;
383   }
384 
385   __android_log_message log_message = {
386       sizeof(__android_log_message), bufID, prio, tag, nullptr, 0, msg};
387   __android_log_write_log_message(&log_message);
388   return 1;
389 }
390 
__android_log_vprint(int prio,const char * tag,const char * fmt,va_list ap)391 int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
392   ErrnoRestorer errno_restorer;
393 
394   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
395     return -EPERM;
396   }
397 
398   __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
399 
400   vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
401 
402   __android_log_message log_message = {
403       sizeof(__android_log_message), LOG_ID_MAIN, prio, tag, nullptr, 0, buf};
404   __android_log_write_log_message(&log_message);
405   return 1;
406 }
407 
__android_log_print(int prio,const char * tag,const char * fmt,...)408 int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
409   ErrnoRestorer errno_restorer;
410 
411   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
412     return -EPERM;
413   }
414 
415   va_list ap;
416   __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
417 
418   va_start(ap, fmt);
419   vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
420   va_end(ap);
421 
422   __android_log_message log_message = {
423       sizeof(__android_log_message), LOG_ID_MAIN, prio, tag, nullptr, 0, buf};
424   __android_log_write_log_message(&log_message);
425   return 1;
426 }
427 
__android_log_buf_print(int bufID,int prio,const char * tag,const char * fmt,...)428 int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
429   ErrnoRestorer errno_restorer;
430 
431   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
432     return -EPERM;
433   }
434 
435   va_list ap;
436   __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
437 
438   va_start(ap, fmt);
439   vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
440   va_end(ap);
441 
442   __android_log_message log_message = {
443       sizeof(__android_log_message), bufID, prio, tag, nullptr, 0, buf};
444   __android_log_write_log_message(&log_message);
445   return 1;
446 }
447 
__android_log_assert(const char * cond,const char * tag,const char * fmt,...)448 void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
449   __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
450 
451   if (fmt) {
452     va_list ap;
453     va_start(ap, fmt);
454     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
455     va_end(ap);
456   } else {
457     /* Msg not provided, log condition.  N.B. Do not use cond directly as
458      * format string as it could contain spurious '%' syntax (e.g.
459      * "%d" in "blocks%devs == 0").
460      */
461     if (cond)
462       snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
463     else
464       strcpy(buf, "Unspecified assertion failed");
465   }
466 
467   // Log assertion failures to stderr for the benefit of "adb shell" users
468   // and gtests (http://b/23675822).
469   TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
470   TEMP_FAILURE_RETRY(write(2, "\n", 1));
471 
472   __android_log_write(ANDROID_LOG_FATAL, tag, buf);
473   __android_log_call_aborter(buf);
474   abort();
475 }
476 
__android_log_bwrite(int32_t tag,const void * payload,size_t len)477 int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
478   ErrnoRestorer errno_restorer;
479 
480   struct iovec vec[2];
481 
482   vec[0].iov_base = &tag;
483   vec[0].iov_len = sizeof(tag);
484   vec[1].iov_base = (void*)payload;
485   vec[1].iov_len = len;
486 
487   return write_to_log(LOG_ID_EVENTS, vec, 2);
488 }
489 
__android_log_stats_bwrite(int32_t tag,const void * payload,size_t len)490 int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
491   ErrnoRestorer errno_restorer;
492 
493   struct iovec vec[2];
494 
495   vec[0].iov_base = &tag;
496   vec[0].iov_len = sizeof(tag);
497   vec[1].iov_base = (void*)payload;
498   vec[1].iov_len = len;
499 
500   return write_to_log(LOG_ID_STATS, vec, 2);
501 }
502 
__android_log_security_bwrite(int32_t tag,const void * payload,size_t len)503 int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
504   ErrnoRestorer errno_restorer;
505 
506   struct iovec vec[2];
507 
508   vec[0].iov_base = &tag;
509   vec[0].iov_len = sizeof(tag);
510   vec[1].iov_base = (void*)payload;
511   vec[1].iov_len = len;
512 
513   return write_to_log(LOG_ID_SECURITY, vec, 2);
514 }
515 
516 /*
517  * Like __android_log_bwrite, but takes the type as well.  Doesn't work
518  * for the general case where we're generating lists of stuff, but very
519  * handy if we just want to dump an integer into the log.
520  */
__android_log_btwrite(int32_t tag,char type,const void * payload,size_t len)521 int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
522   ErrnoRestorer errno_restorer;
523 
524   struct iovec vec[3];
525 
526   vec[0].iov_base = &tag;
527   vec[0].iov_len = sizeof(tag);
528   vec[1].iov_base = &type;
529   vec[1].iov_len = sizeof(type);
530   vec[2].iov_base = (void*)payload;
531   vec[2].iov_len = len;
532 
533   return write_to_log(LOG_ID_EVENTS, vec, 3);
534 }
535 
536 /*
537  * Like __android_log_bwrite, but used for writing strings to the
538  * event log.
539  */
__android_log_bswrite(int32_t tag,const char * payload)540 int __android_log_bswrite(int32_t tag, const char* payload) {
541   ErrnoRestorer errno_restorer;
542 
543   struct iovec vec[4];
544   char type = EVENT_TYPE_STRING;
545   uint32_t len = strlen(payload);
546 
547   vec[0].iov_base = &tag;
548   vec[0].iov_len = sizeof(tag);
549   vec[1].iov_base = &type;
550   vec[1].iov_len = sizeof(type);
551   vec[2].iov_base = &len;
552   vec[2].iov_len = sizeof(len);
553   vec[3].iov_base = (void*)payload;
554   vec[3].iov_len = len;
555 
556   return write_to_log(LOG_ID_EVENTS, vec, 4);
557 }
558 
559 /*
560  * Like __android_log_security_bwrite, but used for writing strings to the
561  * security log.
562  */
__android_log_security_bswrite(int32_t tag,const char * payload)563 int __android_log_security_bswrite(int32_t tag, const char* payload) {
564   ErrnoRestorer errno_restorer;
565 
566   struct iovec vec[4];
567   char type = EVENT_TYPE_STRING;
568   uint32_t len = strlen(payload);
569 
570   vec[0].iov_base = &tag;
571   vec[0].iov_len = sizeof(tag);
572   vec[1].iov_base = &type;
573   vec[1].iov_len = sizeof(type);
574   vec[2].iov_base = &len;
575   vec[2].iov_len = sizeof(len);
576   vec[3].iov_base = (void*)payload;
577   vec[3].iov_len = len;
578 
579   return write_to_log(LOG_ID_SECURITY, vec, 4);
580 }
581