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