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