blob: abcead7b6f791565416e2faf147511a123643966 [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 {
Tom Cherry2187a412019-10-01 17:13:43 -0700283 int prio = *static_cast<int*>(vec[0].iov_base);
284 const char* tag = static_cast<const char*>(vec[1].iov_base);
285 size_t len = vec[1].iov_len;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800286 /* tag must be nul terminated */
Tom Cherry2187a412019-10-01 17:13:43 -0700287 if (strnlen(tag, len) >= len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800288 tag = NULL;
289 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800290
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800291 if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800292 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800293 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800294 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800295 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800296#else
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800297 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
298 {
299 struct timeval tv;
300 gettimeofday(&tv, NULL);
301 ts.tv_sec = tv.tv_sec;
302 ts.tv_nsec = tv.tv_usec * 1000;
303 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800304#endif
305
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800306 ret = 0;
307 i = 1 << log_id;
Tom Cherry2beabe52019-10-01 13:05:58 -0700308
309 if (android_log_write != nullptr && (android_log_write->logMask & i)) {
310 ssize_t retval;
311 retval = android_log_write->write(log_id, &ts, vec, nr);
312 if (ret >= 0) {
313 ret = retval;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800314 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800315 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800316
Tom Cherry2beabe52019-10-01 13:05:58 -0700317 if (android_log_persist_write != nullptr && (android_log_persist_write->logMask & i)) {
318 android_log_persist_write->write(log_id, &ts, vec, nr);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800319 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800320
Mark Salyzyn72d37242018-03-07 10:42:06 -0800321 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800322 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800323}
324
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800325static int __write_to_log_init(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800326 int ret, save_errno = errno;
327
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800328 __android_log_lock();
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800329
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800330 if (write_to_log == __write_to_log_init) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800331 ret = __write_to_log_initialize();
332 if (ret < 0) {
333 __android_log_unlock();
Mark Salyzyn72d37242018-03-07 10:42:06 -0800334 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800335 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800336 }
337
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800338 write_to_log = __write_to_log_daemon;
339 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800340
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800341 __android_log_unlock();
342
Mark Salyzyn72d37242018-03-07 10:42:06 -0800343 ret = write_to_log(log_id, vec, nr);
344 errno = save_errno;
345 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800346}
347
Tom Cherry2d9779e2019-02-08 11:46:19 -0800348int __android_log_write(int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800349 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800350}
351
Tom Cherry2d9779e2019-02-08 11:46:19 -0800352int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800353 if (!tag) tag = "";
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800354
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800355#if __BIONIC__
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800356 if (prio == ANDROID_LOG_FATAL) {
357 android_set_abort_message(msg);
358 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800359#endif
360
Elliott Hughesde3ad1d2015-04-03 13:24:37 -0700361 struct iovec vec[3];
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800362 vec[0].iov_base = (unsigned char*)&prio;
363 vec[0].iov_len = 1;
364 vec[1].iov_base = (void*)tag;
365 vec[1].iov_len = strlen(tag) + 1;
366 vec[2].iov_base = (void*)msg;
367 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800368
Tom Cherry71ba1642019-01-10 10:37:36 -0800369 return write_to_log(static_cast<log_id_t>(bufID), vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800370}
371
Tom Cherry2d9779e2019-02-08 11:46:19 -0800372int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800373 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800374
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800375 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800376
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800377 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800378}
379
Tom Cherry2d9779e2019-02-08 11:46:19 -0800380int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800381 va_list ap;
382 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800383
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800384 va_start(ap, fmt);
385 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
386 va_end(ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800387
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800388 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800389}
390
Tom Cherry2d9779e2019-02-08 11:46:19 -0800391int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800392 va_list ap;
393 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800394
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800395 va_start(ap, fmt);
396 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
397 va_end(ap);
398
399 return __android_log_buf_write(bufID, prio, tag, buf);
400}
401
Tom Cherry2d9779e2019-02-08 11:46:19 -0800402void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800403 char buf[LOG_BUF_SIZE];
404
405 if (fmt) {
406 va_list ap;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800407 va_start(ap, fmt);
408 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
409 va_end(ap);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800410 } else {
411 /* Msg not provided, log condition. N.B. Do not use cond directly as
412 * format string as it could contain spurious '%' syntax (e.g.
413 * "%d" in "blocks%devs == 0").
414 */
415 if (cond)
416 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
417 else
418 strcpy(buf, "Unspecified assertion failed");
419 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800420
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800421 // Log assertion failures to stderr for the benefit of "adb shell" users
422 // and gtests (http://b/23675822).
Tom Cherry6f6ef392019-01-16 14:17:08 -0800423 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
424 TEMP_FAILURE_RETRY(write(2, "\n", 1));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800425
426 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
427 abort(); /* abort so we have a chance to debug the situation */
428 /* NOTREACHED */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800429}
430
Tom Cherry2d9779e2019-02-08 11:46:19 -0800431int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800432 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800433
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800434 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;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800438
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800439 return write_to_log(LOG_ID_EVENTS, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800440}
441
Tom Cherry2d9779e2019-02-08 11:46:19 -0800442int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
Stefan Lafon701a0652017-08-24 20:14:06 -0700443 struct iovec vec[2];
444
445 vec[0].iov_base = &tag;
446 vec[0].iov_len = sizeof(tag);
447 vec[1].iov_base = (void*)payload;
448 vec[1].iov_len = len;
449
450 return write_to_log(LOG_ID_STATS, vec, 2);
451}
452
Tom Cherry2d9779e2019-02-08 11:46:19 -0800453int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800454 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800455
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800456 vec[0].iov_base = &tag;
457 vec[0].iov_len = sizeof(tag);
458 vec[1].iov_base = (void*)payload;
459 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800460
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800461 return write_to_log(LOG_ID_SECURITY, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800462}
463
464/*
465 * Like __android_log_bwrite, but takes the type as well. Doesn't work
466 * for the general case where we're generating lists of stuff, but very
467 * handy if we just want to dump an integer into the log.
468 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800469int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800470 struct iovec vec[3];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800471
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800472 vec[0].iov_base = &tag;
473 vec[0].iov_len = sizeof(tag);
474 vec[1].iov_base = &type;
475 vec[1].iov_len = sizeof(type);
476 vec[2].iov_base = (void*)payload;
477 vec[2].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800478
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800479 return write_to_log(LOG_ID_EVENTS, vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800480}
481
482/*
483 * Like __android_log_bwrite, but used for writing strings to the
484 * event log.
485 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800486int __android_log_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800487 struct iovec vec[4];
488 char type = EVENT_TYPE_STRING;
489 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800490
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800491 vec[0].iov_base = &tag;
492 vec[0].iov_len = sizeof(tag);
493 vec[1].iov_base = &type;
494 vec[1].iov_len = sizeof(type);
495 vec[2].iov_base = &len;
496 vec[2].iov_len = sizeof(len);
497 vec[3].iov_base = (void*)payload;
498 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800499
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800500 return write_to_log(LOG_ID_EVENTS, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800501}
502
503/*
504 * Like __android_log_security_bwrite, but used for writing strings to the
505 * security log.
506 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800507int __android_log_security_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800508 struct iovec vec[4];
509 char type = EVENT_TYPE_STRING;
510 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800511
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800512 vec[0].iov_base = &tag;
513 vec[0].iov_len = sizeof(tag);
514 vec[1].iov_base = &type;
515 vec[1].iov_len = sizeof(type);
516 vec[2].iov_base = &len;
517 vec[2].iov_len = sizeof(len);
518 vec[3].iov_base = (void*)payload;
519 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800520
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800521 return write_to_log(LOG_ID_SECURITY, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800522}