blob: a0f875402697d9f45a0800da86b283019f42b33d [file] [log] [blame]
Mark Salyzyn018a96d2016-03-01 13:45:42 -08001/*
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 <errno.h>
18#include <stdatomic.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/time.h>
22
23#ifdef __BIONIC__
24#include <android/set_abort_message.h>
25#endif
26
27#include <log/event_tag_map.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080028#include <private/android_filesystem_config.h>
29#include <private/android_logger.h>
30
Mark Salyzyn018a96d2016-03-01 13:45:42 -080031#include "log_portability.h"
32#include "logger.h"
Tom Cherry6f6ef392019-01-16 14:17:08 -080033#include "uio.h"
Mark Salyzyn018a96d2016-03-01 13:45:42 -080034
35#define LOG_BUF_SIZE 1024
36
Tom Cherry2beabe52019-10-01 13:05:58 -070037android_log_transport_write* android_log_write = nullptr;
38android_log_transport_write* android_log_persist_write = nullptr;
39
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080040static int __write_to_log_init(log_id_t, struct iovec* vec, size_t nr);
Tom Cherry71ba1642019-01-10 10:37:36 -080041static int (*write_to_log)(log_id_t, struct iovec* vec, size_t nr) = __write_to_log_init;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080042
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080043static int check_log_uid_permissions() {
Dan Willemsen0910d2d2016-11-29 13:39:55 -080044#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080045 uid_t uid = __android_log_uid();
Mark Salyzync33103c2016-03-28 16:20:29 -070046
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080047 /* Matches clientHasLogCredentials() in logd */
48 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
49 uid = geteuid();
Mark Salyzync33103c2016-03-28 16:20:29 -070050 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080051 gid_t gid = getgid();
52 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
53 gid = getegid();
54 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
55 int num_groups;
56 gid_t* groups;
Mark Salyzync33103c2016-03-28 16:20:29 -070057
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080058 num_groups = getgroups(0, NULL);
59 if (num_groups <= 0) {
60 return -EPERM;
61 }
Tom Cherry71ba1642019-01-10 10:37:36 -080062 groups = static_cast<gid_t*>(calloc(num_groups, sizeof(gid_t)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080063 if (!groups) {
64 return -ENOMEM;
65 }
66 num_groups = getgroups(num_groups, groups);
67 while (num_groups > 0) {
68 if (groups[num_groups - 1] == AID_LOG) {
69 break;
Mark Salyzync33103c2016-03-28 16:20:29 -070070 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080071 --num_groups;
72 }
73 free(groups);
74 if (num_groups <= 0) {
75 return -EPERM;
76 }
Mark Salyzync33103c2016-03-28 16:20:29 -070077 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080078 }
Mark Salyzync33103c2016-03-28 16:20:29 -070079 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080080 }
Mark Salyzync33103c2016-03-28 16:20:29 -070081#endif
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080082 return 0;
Mark Salyzync33103c2016-03-28 16:20:29 -070083}
84
Tom Cherry71ba1642019-01-10 10:37:36 -080085static void __android_log_cache_available(struct android_log_transport_write* node) {
86 uint32_t i;
Mark Salyzync33103c2016-03-28 16:20:29 -070087
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080088 if (node->logMask) {
89 return;
90 }
Mark Salyzync33103c2016-03-28 16:20:29 -070091
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080092 for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
93 if (node->write && (i != LOG_ID_KERNEL) &&
94 ((i != LOG_ID_SECURITY) || (check_log_uid_permissions() == 0)) &&
Tom Cherry71ba1642019-01-10 10:37:36 -080095 (!node->available || ((*node->available)(static_cast<log_id_t>(i)) >= 0))) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080096 node->logMask |= 1 << i;
Mark Salyzync33103c2016-03-28 16:20:29 -070097 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080098 }
Mark Salyzync33103c2016-03-28 16:20:29 -070099}
100
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800101#if defined(__ANDROID__)
Mark Salyzynba1a7982016-09-13 07:28:21 -0700102static atomic_uintptr_t tagMap;
103#endif
104
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700105/*
106 * Release any logger resources. A new log write will immediately re-acquire.
107 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800108void __android_log_close() {
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800109#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800110 EventTagMap* m;
Mark Salyzynba1a7982016-09-13 07:28:21 -0700111#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700112
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800113 __android_log_lock();
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700114
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800115 write_to_log = __write_to_log_init;
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700116
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800117 /*
118 * Threads that are actively writing at this point are not held back
119 * by a lock and are at risk of dropping the messages with a return code
120 * -EBADF. Prefer to return error code than add the overhead of a lock to
121 * each log writing call to guarantee delivery. In addition, anyone
122 * calling this is doing so to release the logging resources and shut down,
123 * for them to do so with outstanding log requests in other threads is a
124 * disengenuous use of this function.
125 */
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700126
Tom Cherry2beabe52019-10-01 13:05:58 -0700127 if (android_log_write != nullptr) {
128 android_log_write->close();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800129 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700130
Tom Cherry2beabe52019-10-01 13:05:58 -0700131 if (android_log_persist_write != nullptr) {
132 android_log_persist_write->close();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800133 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700134
Tom Cherry2beabe52019-10-01 13:05:58 -0700135 android_log_write = nullptr;
136 android_log_persist_write = nullptr;
Mark Salyzyn71002882016-03-08 16:18:26 -0800137
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800138#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800139 /*
140 * Additional risk here somewhat mitigated by immediately unlock flushing
141 * the processor cache. The multi-threaded race that we choose to accept,
142 * to minimize locking, is an atomic_load in a writer picking up a value
143 * just prior to entering this routine. There will be an use after free.
144 *
145 * Again, anyone calling this is doing so to release the logging resources
146 * is most probably going to quiesce then shut down; or to restart after
147 * a fork so the risk should be non-existent. For this reason we
148 * choose a mitigation stance for efficiency instead of incuring the cost
149 * of a lock for every log write.
150 */
151 m = (EventTagMap*)atomic_exchange(&tagMap, (uintptr_t)0);
Mark Salyzynba1a7982016-09-13 07:28:21 -0700152#endif
153
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800154 __android_log_unlock();
Mark Salyzynba1a7982016-09-13 07:28:21 -0700155
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800156#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800157 if (m != (EventTagMap*)(uintptr_t)-1LL) android_closeEventTagMap(m);
Mark Salyzynba1a7982016-09-13 07:28:21 -0700158#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700159}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800160
Tom Cherry2beabe52019-10-01 13:05:58 -0700161static bool transport_initialize(android_log_transport_write* transport) {
162 if (transport == nullptr) {
163 return false;
164 }
165
166 __android_log_cache_available(transport);
167 if (!transport->logMask) {
168 return false;
169 }
170
171 // TODO: Do we actually need to call close() if open() fails?
172 if (transport->open() < 0) {
173 transport->close();
174 return false;
175 }
176
177 return true;
178}
179
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800180/* log_init_lock assumed */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800181static int __write_to_log_initialize() {
Tom Cherry2beabe52019-10-01 13:05:58 -0700182#if (FAKE_LOG_DEVICE == 0)
183 extern struct android_log_transport_write logdLoggerWrite;
184 extern struct android_log_transport_write pmsgLoggerWrite;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800185
Tom Cherry2beabe52019-10-01 13:05:58 -0700186 android_log_write = &logdLoggerWrite;
187 android_log_persist_write = &pmsgLoggerWrite;
188#else
189 extern struct android_log_transport_write fakeLoggerWrite;
190
191 android_log_write = &fakeLoggerWrite;
192#endif
193
194 if (!transport_initialize(android_log_write)) {
195 android_log_write = nullptr;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800196 return -ENODEV;
197 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800198
Tom Cherry2beabe52019-10-01 13:05:58 -0700199 if (!transport_initialize(android_log_persist_write)) {
200 android_log_persist_write = nullptr;
201 }
202
203 return 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800204}
205
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800206static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800207 int ret, save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800208 struct timespec ts;
209 size_t len, i;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800210
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800211 for (len = i = 0; i < nr; ++i) {
212 len += vec[i].iov_len;
213 }
214 if (!len) {
215 return -EINVAL;
216 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800217
Mark Salyzyn72d37242018-03-07 10:42:06 -0800218 save_errno = errno;
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800219#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800220 clock_gettime(android_log_clockid(), &ts);
Mark Salyzyn142b43d2016-12-28 10:30:57 -0800221
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800222 if (log_id == LOG_ID_SECURITY) {
223 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800224 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800225 return -EINVAL;
226 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800227
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800228 ret = check_log_uid_permissions();
229 if (ret < 0) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800230 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800231 return ret;
232 }
233 if (!__android_log_security()) {
234 /* If only we could reset downstream logd counter */
Mark Salyzyn72d37242018-03-07 10:42:06 -0800235 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800236 return -EPERM;
237 }
Yao Chen025f05a2017-12-01 15:48:19 -0800238 } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800239 const char* tag;
240 size_t len;
241 EventTagMap *m, *f;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800242
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800243 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800244 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800245 return -EINVAL;
246 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800247
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800248 tag = NULL;
249 len = 0;
250 f = NULL;
251 m = (EventTagMap*)atomic_load(&tagMap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800252
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800253 if (!m) {
254 ret = __android_log_trylock();
255 m = (EventTagMap*)atomic_load(&tagMap); /* trylock flush cache */
256 if (!m) {
257 m = android_openEventTagMap(NULL);
258 if (ret) { /* trylock failed, use local copy, mark for close */
259 f = m;
260 } else {
261 if (!m) { /* One chance to open map file */
262 m = (EventTagMap*)(uintptr_t)-1LL;
263 }
264 atomic_store(&tagMap, (uintptr_t)m);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800265 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800266 }
267 if (!ret) { /* trylock succeeded, unlock */
268 __android_log_unlock();
269 }
270 }
271 if (m && (m != (EventTagMap*)(uintptr_t)-1LL)) {
Tom Cherry7d045f62019-09-30 12:58:55 -0700272 tag = android_lookupEventTag_len(m, &len, *static_cast<uint32_t*>(vec[0].iov_base));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800273 }
Tom Cherry71ba1642019-01-10 10:37:36 -0800274 ret = __android_log_is_loggable_len(ANDROID_LOG_INFO, tag, len, ANDROID_LOG_VERBOSE);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800275 if (f) { /* local copy marked for close */
276 android_closeEventTagMap(f);
277 }
278 if (!ret) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800279 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800280 return -EPERM;
281 }
282 } else {
283 /* Validate the incoming tag, tag content can not split across iovec */
284 char prio = ANDROID_LOG_VERBOSE;
Tom Cherry71ba1642019-01-10 10:37:36 -0800285 const char* tag = static_cast<const char*>(vec[0].iov_base);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800286 size_t len = vec[0].iov_len;
287 if (!tag) {
288 len = 0;
289 }
290 if (len > 0) {
291 prio = *tag;
292 if (len > 1) {
293 --len;
294 ++tag;
295 } else {
296 len = vec[1].iov_len;
297 tag = ((const char*)vec[1].iov_base);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800298 if (!tag) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800299 len = 0;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800300 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800301 }
302 }
303 /* tag must be nul terminated */
304 if (tag && strnlen(tag, len) >= len) {
305 tag = NULL;
306 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800307
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800308 if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800309 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800310 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800311 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800312 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800313#else
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800314 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
315 {
316 struct timeval tv;
317 gettimeofday(&tv, NULL);
318 ts.tv_sec = tv.tv_sec;
319 ts.tv_nsec = tv.tv_usec * 1000;
320 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800321#endif
322
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800323 ret = 0;
324 i = 1 << log_id;
Tom Cherry2beabe52019-10-01 13:05:58 -0700325
326 if (android_log_write != nullptr && (android_log_write->logMask & i)) {
327 ssize_t retval;
328 retval = android_log_write->write(log_id, &ts, vec, nr);
329 if (ret >= 0) {
330 ret = retval;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800331 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800332 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800333
Tom Cherry2beabe52019-10-01 13:05:58 -0700334 if (android_log_persist_write != nullptr && (android_log_persist_write->logMask & i)) {
335 android_log_persist_write->write(log_id, &ts, vec, nr);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800336 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800337
Mark Salyzyn72d37242018-03-07 10:42:06 -0800338 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800339 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800340}
341
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800342static int __write_to_log_init(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800343 int ret, save_errno = errno;
344
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800345 __android_log_lock();
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800346
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800347 if (write_to_log == __write_to_log_init) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800348 ret = __write_to_log_initialize();
349 if (ret < 0) {
350 __android_log_unlock();
Mark Salyzyn72d37242018-03-07 10:42:06 -0800351 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800352 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800353 }
354
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800355 write_to_log = __write_to_log_daemon;
356 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800357
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800358 __android_log_unlock();
359
Mark Salyzyn72d37242018-03-07 10:42:06 -0800360 ret = write_to_log(log_id, vec, nr);
361 errno = save_errno;
362 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800363}
364
Tom Cherry2d9779e2019-02-08 11:46:19 -0800365int __android_log_write(int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800366 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800367}
368
Tom Cherry2d9779e2019-02-08 11:46:19 -0800369int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800370 if (!tag) tag = "";
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800371
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800372#if __BIONIC__
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800373 if (prio == ANDROID_LOG_FATAL) {
374 android_set_abort_message(msg);
375 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800376#endif
377
Elliott Hughesde3ad1d2015-04-03 13:24:37 -0700378 struct iovec vec[3];
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800379 vec[0].iov_base = (unsigned char*)&prio;
380 vec[0].iov_len = 1;
381 vec[1].iov_base = (void*)tag;
382 vec[1].iov_len = strlen(tag) + 1;
383 vec[2].iov_base = (void*)msg;
384 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800385
Tom Cherry71ba1642019-01-10 10:37:36 -0800386 return write_to_log(static_cast<log_id_t>(bufID), vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800387}
388
Tom Cherry2d9779e2019-02-08 11:46:19 -0800389int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800390 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800391
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800392 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800393
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800394 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800395}
396
Tom Cherry2d9779e2019-02-08 11:46:19 -0800397int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800398 va_list ap;
399 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800400
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800401 va_start(ap, fmt);
402 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
403 va_end(ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800404
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800405 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800406}
407
Tom Cherry2d9779e2019-02-08 11:46:19 -0800408int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800409 va_list ap;
410 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800411
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800412 va_start(ap, fmt);
413 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
414 va_end(ap);
415
416 return __android_log_buf_write(bufID, prio, tag, buf);
417}
418
Tom Cherry2d9779e2019-02-08 11:46:19 -0800419void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800420 char buf[LOG_BUF_SIZE];
421
422 if (fmt) {
423 va_list ap;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800424 va_start(ap, fmt);
425 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
426 va_end(ap);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800427 } else {
428 /* Msg not provided, log condition. N.B. Do not use cond directly as
429 * format string as it could contain spurious '%' syntax (e.g.
430 * "%d" in "blocks%devs == 0").
431 */
432 if (cond)
433 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
434 else
435 strcpy(buf, "Unspecified assertion failed");
436 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800437
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800438 // Log assertion failures to stderr for the benefit of "adb shell" users
439 // and gtests (http://b/23675822).
Tom Cherry6f6ef392019-01-16 14:17:08 -0800440 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
441 TEMP_FAILURE_RETRY(write(2, "\n", 1));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800442
443 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
444 abort(); /* abort so we have a chance to debug the situation */
445 /* NOTREACHED */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800446}
447
Tom Cherry2d9779e2019-02-08 11:46:19 -0800448int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800449 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800450
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800451 vec[0].iov_base = &tag;
452 vec[0].iov_len = sizeof(tag);
453 vec[1].iov_base = (void*)payload;
454 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800455
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800456 return write_to_log(LOG_ID_EVENTS, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800457}
458
Tom Cherry2d9779e2019-02-08 11:46:19 -0800459int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
Stefan Lafon701a0652017-08-24 20:14:06 -0700460 struct iovec vec[2];
461
462 vec[0].iov_base = &tag;
463 vec[0].iov_len = sizeof(tag);
464 vec[1].iov_base = (void*)payload;
465 vec[1].iov_len = len;
466
467 return write_to_log(LOG_ID_STATS, vec, 2);
468}
469
Tom Cherry2d9779e2019-02-08 11:46:19 -0800470int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800471 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800472
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800473 vec[0].iov_base = &tag;
474 vec[0].iov_len = sizeof(tag);
475 vec[1].iov_base = (void*)payload;
476 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800477
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800478 return write_to_log(LOG_ID_SECURITY, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800479}
480
481/*
482 * Like __android_log_bwrite, but takes the type as well. Doesn't work
483 * for the general case where we're generating lists of stuff, but very
484 * handy if we just want to dump an integer into the log.
485 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800486int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800487 struct iovec vec[3];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800488
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800489 vec[0].iov_base = &tag;
490 vec[0].iov_len = sizeof(tag);
491 vec[1].iov_base = &type;
492 vec[1].iov_len = sizeof(type);
493 vec[2].iov_base = (void*)payload;
494 vec[2].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800495
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800496 return write_to_log(LOG_ID_EVENTS, vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800497}
498
499/*
500 * Like __android_log_bwrite, but used for writing strings to the
501 * event log.
502 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800503int __android_log_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800504 struct iovec vec[4];
505 char type = EVENT_TYPE_STRING;
506 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800507
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800508 vec[0].iov_base = &tag;
509 vec[0].iov_len = sizeof(tag);
510 vec[1].iov_base = &type;
511 vec[1].iov_len = sizeof(type);
512 vec[2].iov_base = &len;
513 vec[2].iov_len = sizeof(len);
514 vec[3].iov_base = (void*)payload;
515 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800516
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800517 return write_to_log(LOG_ID_EVENTS, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800518}
519
520/*
521 * Like __android_log_security_bwrite, but used for writing strings to the
522 * security log.
523 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800524int __android_log_security_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800525 struct iovec vec[4];
526 char type = EVENT_TYPE_STRING;
527 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800528
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800529 vec[0].iov_base = &tag;
530 vec[0].iov_len = sizeof(tag);
531 vec[1].iov_base = &type;
532 vec[1].iov_len = sizeof(type);
533 vec[2].iov_base = &len;
534 vec[2].iov_len = sizeof(len);
535 vec[3].iov_base = (void*)payload;
536 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800537
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800538 return write_to_log(LOG_ID_SECURITY, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800539}