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