• 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,const struct timespec * timestamp=nullptr)199 static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr,
200                         const struct timespec* timestamp = nullptr) {
201   if (log_id == LOG_ID_KERNEL) {
202     return -EINVAL;
203   }
204 
205   struct timespec ts;
206   if (LIKELY(timestamp == nullptr)) {
207     clock_gettime(CLOCK_REALTIME, &ts);
208     timestamp = &ts;
209   }
210 
211   if (log_id == LOG_ID_SECURITY) {
212     if (vec[0].iov_len < 4) {
213       return -EINVAL;
214     }
215 
216     int ret = check_log_uid_permissions();
217     if (ret < 0) {
218       return ret;
219     }
220     if (!__android_log_security()) {
221       /* If only we could reset downstream logd counter */
222       return -EPERM;
223     }
224   } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
225     if (vec[0].iov_len < 4) {
226       return -EINVAL;
227     }
228   }
229 
230   int ret = LogdWrite(log_id, timestamp, vec, nr);
231   PmsgWrite(log_id, timestamp, vec, nr);
232 
233   return ret;
234 }
235 #else
write_to_log(log_id_t,struct iovec *,size_t,const struct timespec * =nullptr)236 static int write_to_log(log_id_t, struct iovec*, size_t, const struct timespec* = nullptr) {
237   // Non-Android text logs should go to __android_log_stderr_logger, not here.
238   // Non-Android binary logs are always dropped.
239   return 1;
240 }
241 #endif
242 
243 // Copied from base/threads.cpp
GetThreadId()244 static uint64_t GetThreadId() {
245 #if defined(__BIONIC__)
246   return gettid();
247 #elif defined(__APPLE__)
248   uint64_t tid;
249   pthread_threadid_np(NULL, &tid);
250   return tid;
251 #elif defined(__linux__)
252   return syscall(__NR_gettid);
253 #elif defined(_WIN32)
254   return GetCurrentThreadId();
255 #endif
256 }
257 
filestream_logger(const struct __android_log_message * log_message,FILE * stream)258 static void filestream_logger(const struct __android_log_message* log_message, FILE* stream) {
259   struct timespec ts;
260   clock_gettime(CLOCK_REALTIME, &ts);
261 
262   struct tm now;
263   localtime_r(&ts.tv_sec, &now);
264 
265   char timestamp[sizeof("mm-DD HH::MM::SS.mmm\0")];
266   size_t n = strftime(timestamp, sizeof(timestamp), "%m-%d %H:%M:%S", &now);
267   snprintf(timestamp + n, sizeof(timestamp) - n, ".%03ld", ts.tv_nsec / (1000 * 1000));
268 
269   static const char log_characters[] = "XXVDIWEF";
270   static_assert(arraysize(log_characters) - 1 == ANDROID_LOG_SILENT,
271                 "Mismatch in size of log_characters and values in android_LogPriority");
272   int32_t priority =
273       log_message->priority > ANDROID_LOG_SILENT ? ANDROID_LOG_FATAL : log_message->priority;
274   char priority_char = log_characters[priority];
275   uint64_t tid = GetThreadId();
276   const char* tag = log_message->tag ? log_message->tag : " nullptr";
277 
278   if (log_message->file != nullptr) {
279     fprintf(stream, "%s %5d %5" PRIu64 " %c %-8s: %s:%u %s\n", timestamp, getpid(), tid,
280             priority_char, tag, log_message->file, log_message->line, log_message->message);
281   } else {
282     fprintf(stream, "%s %5d %5" PRIu64 " %c %-8s: %s\n", timestamp, getpid(), tid, priority_char,
283             tag, log_message->message);
284   }
285 }
286 
get_file_logger_path()287 static const char* get_file_logger_path() {
288 #ifdef __ANDROID__
289   static const char* file_logger_path = []() {
290     static char path[PROP_VALUE_MAX] = {};
291     if (__system_property_get("ro.log.file_logger.path", path) > 0) {
292       return path;
293     }
294     return static_cast<char*>(nullptr);  // means file_logger should not be used
295   }();
296   return file_logger_path;
297 #else
298   return nullptr;
299 #endif
300 }
301 
302 /*
303  * If ro.log.file_logger.path is set to a file, send log_message to the file instead. This is for
304  * Android-like environments where logd is not available; e.g. Microdroid. If the file is not
305  * accessible (but ro.log.file_logger.path is set anyway), stderr is chosen as the fallback.
306  *
307  * Returns true if log was sent to file. false, if not.
308  */
log_to_file_if_overridden(const struct __android_log_message * log_message)309 static bool log_to_file_if_overridden(const struct __android_log_message* log_message) {
310   const char* file_logger_path = get_file_logger_path();
311   if (file_logger_path == nullptr) return false;
312 
313   static FILE* stream = [&file_logger_path]() {
314     FILE* f = fopen(file_logger_path, "ae");
315     if (f != nullptr) return f;
316     using namespace std::string_literals;
317     std::string err_msg = "Cannot open "s + file_logger_path + " for logging: (" + strerror(errno) +
318                           "). Falling back to stderr";
319     __android_log_message m = {sizeof(__android_log_message),
320                                LOG_ID_DEFAULT,
321                                ANDROID_LOG_WARN,
322                                "liblog",
323                                __FILE__,
324                                __LINE__,
325                                err_msg.c_str()};
326     filestream_logger(&m, stderr);
327     return stderr;
328   }();
329   filestream_logger(log_message, stream);
330   return true;
331 }
332 
__android_log_stderr_logger(const struct __android_log_message * log_message)333 void __android_log_stderr_logger(const struct __android_log_message* log_message) {
334   filestream_logger(log_message, stderr);
335 }
336 
__android_log_logd_logger(const struct __android_log_message * log_message)337 void __android_log_logd_logger(const struct __android_log_message* log_message) {
338   __android_log_logd_logger_with_timestamp(log_message, nullptr);
339 }
340 
__android_log_logd_logger_with_timestamp(const struct __android_log_message * log_message,const struct timespec * timestamp)341 void __android_log_logd_logger_with_timestamp(const struct __android_log_message* log_message,
342                                               const struct timespec* timestamp) {
343   if (log_to_file_if_overridden(log_message)) return;
344 
345   int buffer_id = log_message->buffer_id == LOG_ID_DEFAULT ? LOG_ID_MAIN : log_message->buffer_id;
346 
347   struct iovec vec[3];
348   vec[0].iov_base =
349       const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(&log_message->priority));
350   vec[0].iov_len = 1;
351   vec[1].iov_base = const_cast<void*>(static_cast<const void*>(log_message->tag));
352   vec[1].iov_len = strlen(log_message->tag) + 1;
353   vec[2].iov_base = const_cast<void*>(static_cast<const void*>(log_message->message));
354   vec[2].iov_len = strlen(log_message->message) + 1;
355 
356   write_to_log(static_cast<log_id_t>(buffer_id), vec, 3, timestamp);
357 }
358 
__android_log_write(int prio,const char * tag,const char * msg)359 int __android_log_write(int prio, const char* tag, const char* msg) {
360   return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
361 }
362 
__android_log_write_log_message(__android_log_message * log_message)363 void __android_log_write_log_message(__android_log_message* log_message) {
364   ErrnoRestorer errno_restorer;
365 
366   if (log_message->buffer_id != LOG_ID_DEFAULT && log_message->buffer_id != LOG_ID_MAIN &&
367       log_message->buffer_id != LOG_ID_SYSTEM && log_message->buffer_id != LOG_ID_RADIO &&
368       log_message->buffer_id != LOG_ID_CRASH) {
369     return;
370   }
371 
372   if (log_message->tag == nullptr) {
373     log_message->tag = GetDefaultTag().c_str();
374   }
375 
376 #if __BIONIC__
377   if (log_message->priority == ANDROID_LOG_FATAL) {
378     android_set_abort_message(log_message->message);
379   }
380 #endif
381 
382   logger_function(log_message);
383 }
384 
__android_log_buf_write(int log_id,int prio,const char * tag,const char * msg)385 int __android_log_buf_write(int log_id, int prio, const char* tag, const char* msg) {
386   ErrnoRestorer errno_restorer;
387 
388   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
389     return -EPERM;
390   }
391 
392   __android_log_message log_message = {
393       sizeof(__android_log_message), log_id, prio, tag, nullptr, 0, msg};
394   __android_log_write_log_message(&log_message);
395   return 1;
396 }
397 
__android_log_vprint(int prio,const char * tag,const char * fmt,va_list ap)398 int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
399   ErrnoRestorer errno_restorer;
400 
401   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
402     return -EPERM;
403   }
404 
405   __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
406 
407   vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
408 
409   __android_log_message log_message = {
410       sizeof(__android_log_message), LOG_ID_MAIN, prio, tag, nullptr, 0, buf};
411   __android_log_write_log_message(&log_message);
412   return 1;
413 }
414 
__android_log_print(int prio,const char * tag,const char * fmt,...)415 int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
416   ErrnoRestorer errno_restorer;
417 
418   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
419     return -EPERM;
420   }
421 
422   va_list ap;
423   __attribute__((uninitialized)) 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   __android_log_message log_message = {
430       sizeof(__android_log_message), LOG_ID_MAIN, prio, tag, nullptr, 0, buf};
431   __android_log_write_log_message(&log_message);
432   return 1;
433 }
434 
__android_log_buf_print(int log_id,int prio,const char * tag,const char * fmt,...)435 int __android_log_buf_print(int log_id, int prio, const char* tag, const char* fmt, ...) {
436   ErrnoRestorer errno_restorer;
437 
438   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
439     return -EPERM;
440   }
441 
442   va_list ap;
443   __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
444 
445   va_start(ap, fmt);
446   vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
447   va_end(ap);
448 
449   __android_log_message log_message = {
450       sizeof(__android_log_message), log_id, prio, tag, nullptr, 0, buf};
451   __android_log_write_log_message(&log_message);
452   return 1;
453 }
454 
__android_log_assert(const char * cond,const char * tag,const char * fmt,...)455 void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
456   __attribute__((uninitialized)) char buf[LOG_BUF_SIZE];
457 
458   if (fmt) {
459     va_list ap;
460     va_start(ap, fmt);
461     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
462     va_end(ap);
463   } else {
464     /* Msg not provided, log condition.  N.B. Do not use cond directly as
465      * format string as it could contain spurious '%' syntax (e.g.
466      * "%d" in "blocks%devs == 0").
467      */
468     if (cond)
469       snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
470     else
471       strcpy(buf, "Unspecified assertion failed");
472   }
473 
474   // Log assertion failures to stderr for the benefit of "adb shell" users
475   // and gtests (http://b/23675822).
476   TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
477   TEMP_FAILURE_RETRY(write(2, "\n", 1));
478 
479   __android_log_write(ANDROID_LOG_FATAL, tag, buf);
480   __android_log_call_aborter(buf);
481   abort();
482 }
483 
__android_log_bwrite(int32_t tag,const void * payload,size_t len)484 int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
485   ErrnoRestorer errno_restorer;
486 
487   struct iovec vec[2];
488 
489   vec[0].iov_base = &tag;
490   vec[0].iov_len = sizeof(tag);
491   vec[1].iov_base = (void*)payload;
492   vec[1].iov_len = len;
493 
494   return write_to_log(LOG_ID_EVENTS, vec, 2);
495 }
496 
__android_log_stats_bwrite(int32_t tag,const void * payload,size_t len)497 int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
498   ErrnoRestorer errno_restorer;
499 
500   struct iovec vec[2];
501 
502   vec[0].iov_base = &tag;
503   vec[0].iov_len = sizeof(tag);
504   vec[1].iov_base = (void*)payload;
505   vec[1].iov_len = len;
506 
507   return write_to_log(LOG_ID_STATS, vec, 2);
508 }
509 
__android_log_security_bwrite(int32_t tag,const void * payload,size_t len)510 int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
511   ErrnoRestorer errno_restorer;
512 
513   struct iovec vec[2];
514 
515   vec[0].iov_base = &tag;
516   vec[0].iov_len = sizeof(tag);
517   vec[1].iov_base = (void*)payload;
518   vec[1].iov_len = len;
519 
520   return write_to_log(LOG_ID_SECURITY, vec, 2);
521 }
522 
523 /*
524  * Like __android_log_bwrite, but takes the type as well.  Doesn't work
525  * for the general case where we're generating lists of stuff, but very
526  * handy if we just want to dump an integer into the log.
527  */
__android_log_btwrite(int32_t tag,char type,const void * payload,size_t len)528 int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
529   ErrnoRestorer errno_restorer;
530 
531   struct iovec vec[3];
532 
533   vec[0].iov_base = &tag;
534   vec[0].iov_len = sizeof(tag);
535   vec[1].iov_base = &type;
536   vec[1].iov_len = sizeof(type);
537   vec[2].iov_base = (void*)payload;
538   vec[2].iov_len = len;
539 
540   return write_to_log(LOG_ID_EVENTS, vec, 3);
541 }
542 
543 /*
544  * Like __android_log_bwrite, but used for writing strings to the
545  * event log.
546  */
__android_log_bswrite(int32_t tag,const char * payload)547 int __android_log_bswrite(int32_t tag, const char* payload) {
548   ErrnoRestorer errno_restorer;
549 
550   struct iovec vec[4];
551   char type = EVENT_TYPE_STRING;
552   uint32_t len = strlen(payload);
553 
554   vec[0].iov_base = &tag;
555   vec[0].iov_len = sizeof(tag);
556   vec[1].iov_base = &type;
557   vec[1].iov_len = sizeof(type);
558   vec[2].iov_base = &len;
559   vec[2].iov_len = sizeof(len);
560   vec[3].iov_base = (void*)payload;
561   vec[3].iov_len = len;
562 
563   return write_to_log(LOG_ID_EVENTS, vec, 4);
564 }
565 
566 /*
567  * Like __android_log_security_bwrite, but used for writing strings to the
568  * security log.
569  */
__android_log_security_bswrite(int32_t tag,const char * payload)570 int __android_log_security_bswrite(int32_t tag, const char* payload) {
571   ErrnoRestorer errno_restorer;
572 
573   struct iovec vec[4];
574   char type = EVENT_TYPE_STRING;
575   uint32_t len = strlen(payload);
576 
577   vec[0].iov_base = &tag;
578   vec[0].iov_len = sizeof(tag);
579   vec[1].iov_base = &type;
580   vec[1].iov_len = sizeof(type);
581   vec[2].iov_base = &len;
582   vec[2].iov_len = sizeof(len);
583   vec[3].iov_base = (void*)payload;
584   vec[3].iov_len = len;
585 
586   return write_to_log(LOG_ID_SECURITY, vec, 4);
587 }
588