blob: e1772f1909bcda5fd820976c6f2fdd0eba001043 [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 Cherry97ec4ee2019-10-02 10:52:55 -070037#if (FAKE_LOG_DEVICE == 0)
38extern struct android_log_transport_write logdLoggerWrite;
39extern struct android_log_transport_write pmsgLoggerWrite;
40
41android_log_transport_write* android_log_write = &logdLoggerWrite;
42android_log_transport_write* android_log_persist_write = &pmsgLoggerWrite;
43#else
44extern android_log_transport_write fakeLoggerWrite;
45
46android_log_transport_write* android_log_write = &fakeLoggerWrite;
Tom Cherry2beabe52019-10-01 13:05:58 -070047android_log_transport_write* android_log_persist_write = nullptr;
Tom Cherry97ec4ee2019-10-02 10:52:55 -070048#endif
Tom Cherry2beabe52019-10-01 13:05:58 -070049
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080050static int __write_to_log_init(log_id_t, struct iovec* vec, size_t nr);
Tom Cherry71ba1642019-01-10 10:37:36 -080051static int (*write_to_log)(log_id_t, struct iovec* vec, size_t nr) = __write_to_log_init;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080052
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080053static int check_log_uid_permissions() {
Dan Willemsen0910d2d2016-11-29 13:39:55 -080054#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080055 uid_t uid = __android_log_uid();
Mark Salyzync33103c2016-03-28 16:20:29 -070056
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080057 /* Matches clientHasLogCredentials() in logd */
58 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
59 uid = geteuid();
Mark Salyzync33103c2016-03-28 16:20:29 -070060 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080061 gid_t gid = getgid();
62 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
63 gid = getegid();
64 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
65 int num_groups;
66 gid_t* groups;
Mark Salyzync33103c2016-03-28 16:20:29 -070067
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080068 num_groups = getgroups(0, NULL);
69 if (num_groups <= 0) {
70 return -EPERM;
71 }
Tom Cherry71ba1642019-01-10 10:37:36 -080072 groups = static_cast<gid_t*>(calloc(num_groups, sizeof(gid_t)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080073 if (!groups) {
74 return -ENOMEM;
75 }
76 num_groups = getgroups(num_groups, groups);
77 while (num_groups > 0) {
78 if (groups[num_groups - 1] == AID_LOG) {
79 break;
Mark Salyzync33103c2016-03-28 16:20:29 -070080 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080081 --num_groups;
82 }
83 free(groups);
84 if (num_groups <= 0) {
85 return -EPERM;
86 }
Mark Salyzync33103c2016-03-28 16:20:29 -070087 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080088 }
Mark Salyzync33103c2016-03-28 16:20:29 -070089 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080090 }
Mark Salyzync33103c2016-03-28 16:20:29 -070091#endif
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080092 return 0;
Mark Salyzync33103c2016-03-28 16:20:29 -070093}
94
Tom Cherry71ba1642019-01-10 10:37:36 -080095static void __android_log_cache_available(struct android_log_transport_write* node) {
96 uint32_t i;
Mark Salyzync33103c2016-03-28 16:20:29 -070097
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080098 if (node->logMask) {
99 return;
100 }
Mark Salyzync33103c2016-03-28 16:20:29 -0700101
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800102 for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
Tom Cherry990852f2019-10-02 10:34:03 -0700103 if (i != LOG_ID_KERNEL && (i != LOG_ID_SECURITY || check_log_uid_permissions() == 0) &&
104 (*node->available)(static_cast<log_id_t>(i)) >= 0) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800105 node->logMask |= 1 << i;
Mark Salyzync33103c2016-03-28 16:20:29 -0700106 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800107 }
Mark Salyzync33103c2016-03-28 16:20:29 -0700108}
109
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800110#if defined(__ANDROID__)
Mark Salyzynba1a7982016-09-13 07:28:21 -0700111static atomic_uintptr_t tagMap;
112#endif
113
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700114/*
115 * Release any logger resources. A new log write will immediately re-acquire.
116 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800117void __android_log_close() {
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800118#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800119 EventTagMap* m;
Mark Salyzynba1a7982016-09-13 07:28:21 -0700120#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700121
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800122 __android_log_lock();
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700123
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800124 write_to_log = __write_to_log_init;
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700125
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800126 /*
127 * Threads that are actively writing at this point are not held back
128 * by a lock and are at risk of dropping the messages with a return code
129 * -EBADF. Prefer to return error code than add the overhead of a lock to
130 * each log writing call to guarantee delivery. In addition, anyone
131 * calling this is doing so to release the logging resources and shut down,
132 * for them to do so with outstanding log requests in other threads is a
133 * disengenuous use of this function.
134 */
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700135
Tom Cherry2beabe52019-10-01 13:05:58 -0700136 if (android_log_write != nullptr) {
137 android_log_write->close();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800138 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700139
Tom Cherry2beabe52019-10-01 13:05:58 -0700140 if (android_log_persist_write != nullptr) {
141 android_log_persist_write->close();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800142 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700143
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800144#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800145 /*
146 * Additional risk here somewhat mitigated by immediately unlock flushing
147 * the processor cache. The multi-threaded race that we choose to accept,
148 * to minimize locking, is an atomic_load in a writer picking up a value
149 * just prior to entering this routine. There will be an use after free.
150 *
151 * Again, anyone calling this is doing so to release the logging resources
152 * is most probably going to quiesce then shut down; or to restart after
153 * a fork so the risk should be non-existent. For this reason we
154 * choose a mitigation stance for efficiency instead of incuring the cost
155 * of a lock for every log write.
156 */
157 m = (EventTagMap*)atomic_exchange(&tagMap, (uintptr_t)0);
Mark Salyzynba1a7982016-09-13 07:28:21 -0700158#endif
159
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800160 __android_log_unlock();
Mark Salyzynba1a7982016-09-13 07:28:21 -0700161
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800162#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800163 if (m != (EventTagMap*)(uintptr_t)-1LL) android_closeEventTagMap(m);
Mark Salyzynba1a7982016-09-13 07:28:21 -0700164#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700165}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800166
Tom Cherry2beabe52019-10-01 13:05:58 -0700167static bool transport_initialize(android_log_transport_write* transport) {
168 if (transport == nullptr) {
169 return false;
170 }
171
172 __android_log_cache_available(transport);
173 if (!transport->logMask) {
174 return false;
175 }
176
177 // TODO: Do we actually need to call close() if open() fails?
178 if (transport->open() < 0) {
179 transport->close();
180 return false;
181 }
182
183 return true;
184}
185
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800186/* log_init_lock assumed */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800187static int __write_to_log_initialize() {
Tom Cherry2beabe52019-10-01 13:05:58 -0700188 if (!transport_initialize(android_log_write)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800189 return -ENODEV;
190 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800191
Tom Cherry97ec4ee2019-10-02 10:52:55 -0700192 transport_initialize(android_log_persist_write);
Tom Cherry2beabe52019-10-01 13:05:58 -0700193
194 return 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800195}
196
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800197static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800198 int ret, save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800199 struct timespec ts;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800200
Mark Salyzyn72d37242018-03-07 10:42:06 -0800201 save_errno = errno;
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800202#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800203 clock_gettime(android_log_clockid(), &ts);
Mark Salyzyn142b43d2016-12-28 10:30:57 -0800204
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800205 if (log_id == LOG_ID_SECURITY) {
206 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800207 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800208 return -EINVAL;
209 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800210
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800211 ret = check_log_uid_permissions();
212 if (ret < 0) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800213 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800214 return ret;
215 }
216 if (!__android_log_security()) {
217 /* If only we could reset downstream logd counter */
Mark Salyzyn72d37242018-03-07 10:42:06 -0800218 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800219 return -EPERM;
220 }
Yao Chen025f05a2017-12-01 15:48:19 -0800221 } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800222 const char* tag;
223 size_t len;
224 EventTagMap *m, *f;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800225
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800226 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800227 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800228 return -EINVAL;
229 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800230
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800231 tag = NULL;
232 len = 0;
233 f = NULL;
234 m = (EventTagMap*)atomic_load(&tagMap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800235
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800236 if (!m) {
237 ret = __android_log_trylock();
238 m = (EventTagMap*)atomic_load(&tagMap); /* trylock flush cache */
239 if (!m) {
240 m = android_openEventTagMap(NULL);
241 if (ret) { /* trylock failed, use local copy, mark for close */
242 f = m;
243 } else {
244 if (!m) { /* One chance to open map file */
245 m = (EventTagMap*)(uintptr_t)-1LL;
246 }
247 atomic_store(&tagMap, (uintptr_t)m);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800248 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800249 }
250 if (!ret) { /* trylock succeeded, unlock */
251 __android_log_unlock();
252 }
253 }
254 if (m && (m != (EventTagMap*)(uintptr_t)-1LL)) {
Tom Cherry7d045f62019-09-30 12:58:55 -0700255 tag = android_lookupEventTag_len(m, &len, *static_cast<uint32_t*>(vec[0].iov_base));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800256 }
Tom Cherry71ba1642019-01-10 10:37:36 -0800257 ret = __android_log_is_loggable_len(ANDROID_LOG_INFO, tag, len, ANDROID_LOG_VERBOSE);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800258 if (f) { /* local copy marked for close */
259 android_closeEventTagMap(f);
260 }
261 if (!ret) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800262 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800263 return -EPERM;
264 }
265 } else {
Tom Cherry2187a412019-10-01 17:13:43 -0700266 int prio = *static_cast<int*>(vec[0].iov_base);
267 const char* tag = static_cast<const char*>(vec[1].iov_base);
268 size_t len = vec[1].iov_len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800269
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800270 if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800271 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800272 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800273 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800274 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800275#else
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800276 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
277 {
278 struct timeval tv;
279 gettimeofday(&tv, NULL);
280 ts.tv_sec = tv.tv_sec;
281 ts.tv_nsec = tv.tv_usec * 1000;
282 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800283#endif
284
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800285 ret = 0;
Tom Cherry990852f2019-10-02 10:34:03 -0700286 size_t i = 1 << log_id;
Tom Cherry2beabe52019-10-01 13:05:58 -0700287
288 if (android_log_write != nullptr && (android_log_write->logMask & i)) {
289 ssize_t retval;
290 retval = android_log_write->write(log_id, &ts, vec, nr);
291 if (ret >= 0) {
292 ret = retval;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800293 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800294 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800295
Tom Cherry2beabe52019-10-01 13:05:58 -0700296 if (android_log_persist_write != nullptr && (android_log_persist_write->logMask & i)) {
297 android_log_persist_write->write(log_id, &ts, vec, nr);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800298 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800299
Mark Salyzyn72d37242018-03-07 10:42:06 -0800300 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800301 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800302}
303
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800304static int __write_to_log_init(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800305 int ret, save_errno = errno;
306
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800307 __android_log_lock();
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800308
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800309 if (write_to_log == __write_to_log_init) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800310 ret = __write_to_log_initialize();
311 if (ret < 0) {
312 __android_log_unlock();
Mark Salyzyn72d37242018-03-07 10:42:06 -0800313 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800314 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800315 }
316
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800317 write_to_log = __write_to_log_daemon;
318 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800319
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800320 __android_log_unlock();
321
Mark Salyzyn72d37242018-03-07 10:42:06 -0800322 ret = write_to_log(log_id, vec, nr);
323 errno = save_errno;
324 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800325}
326
Tom Cherry2d9779e2019-02-08 11:46:19 -0800327int __android_log_write(int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800328 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800329}
330
Tom Cherry2d9779e2019-02-08 11:46:19 -0800331int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800332 if (!tag) tag = "";
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800333
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800334#if __BIONIC__
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800335 if (prio == ANDROID_LOG_FATAL) {
336 android_set_abort_message(msg);
337 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800338#endif
339
Elliott Hughesde3ad1d2015-04-03 13:24:37 -0700340 struct iovec vec[3];
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800341 vec[0].iov_base = (unsigned char*)&prio;
342 vec[0].iov_len = 1;
343 vec[1].iov_base = (void*)tag;
344 vec[1].iov_len = strlen(tag) + 1;
345 vec[2].iov_base = (void*)msg;
346 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800347
Tom Cherry71ba1642019-01-10 10:37:36 -0800348 return write_to_log(static_cast<log_id_t>(bufID), vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800349}
350
Tom Cherry2d9779e2019-02-08 11:46:19 -0800351int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800352 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800353
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800354 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800355
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800356 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800357}
358
Tom Cherry2d9779e2019-02-08 11:46:19 -0800359int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800360 va_list ap;
361 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800362
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800363 va_start(ap, fmt);
364 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
365 va_end(ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800366
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800367 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800368}
369
Tom Cherry2d9779e2019-02-08 11:46:19 -0800370int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800371 va_list ap;
372 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800373
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800374 va_start(ap, fmt);
375 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
376 va_end(ap);
377
378 return __android_log_buf_write(bufID, prio, tag, buf);
379}
380
Tom Cherry2d9779e2019-02-08 11:46:19 -0800381void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800382 char buf[LOG_BUF_SIZE];
383
384 if (fmt) {
385 va_list ap;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800386 va_start(ap, fmt);
387 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
388 va_end(ap);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800389 } else {
390 /* Msg not provided, log condition. N.B. Do not use cond directly as
391 * format string as it could contain spurious '%' syntax (e.g.
392 * "%d" in "blocks%devs == 0").
393 */
394 if (cond)
395 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
396 else
397 strcpy(buf, "Unspecified assertion failed");
398 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800399
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800400 // Log assertion failures to stderr for the benefit of "adb shell" users
401 // and gtests (http://b/23675822).
Tom Cherry6f6ef392019-01-16 14:17:08 -0800402 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
403 TEMP_FAILURE_RETRY(write(2, "\n", 1));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800404
405 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
406 abort(); /* abort so we have a chance to debug the situation */
407 /* NOTREACHED */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800408}
409
Tom Cherry2d9779e2019-02-08 11:46:19 -0800410int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800411 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800412
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800413 vec[0].iov_base = &tag;
414 vec[0].iov_len = sizeof(tag);
415 vec[1].iov_base = (void*)payload;
416 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800417
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800418 return write_to_log(LOG_ID_EVENTS, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800419}
420
Tom Cherry2d9779e2019-02-08 11:46:19 -0800421int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
Stefan Lafon701a0652017-08-24 20:14:06 -0700422 struct iovec vec[2];
423
424 vec[0].iov_base = &tag;
425 vec[0].iov_len = sizeof(tag);
426 vec[1].iov_base = (void*)payload;
427 vec[1].iov_len = len;
428
429 return write_to_log(LOG_ID_STATS, vec, 2);
430}
431
Tom Cherry2d9779e2019-02-08 11:46:19 -0800432int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800433 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800434
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800435 vec[0].iov_base = &tag;
436 vec[0].iov_len = sizeof(tag);
437 vec[1].iov_base = (void*)payload;
438 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800439
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800440 return write_to_log(LOG_ID_SECURITY, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800441}
442
443/*
444 * Like __android_log_bwrite, but takes the type as well. Doesn't work
445 * for the general case where we're generating lists of stuff, but very
446 * handy if we just want to dump an integer into the log.
447 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800448int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800449 struct iovec vec[3];
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 = &type;
454 vec[1].iov_len = sizeof(type);
455 vec[2].iov_base = (void*)payload;
456 vec[2].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800457
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800458 return write_to_log(LOG_ID_EVENTS, vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800459}
460
461/*
462 * Like __android_log_bwrite, but used for writing strings to the
463 * event log.
464 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800465int __android_log_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800466 struct iovec vec[4];
467 char type = EVENT_TYPE_STRING;
468 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800469
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800470 vec[0].iov_base = &tag;
471 vec[0].iov_len = sizeof(tag);
472 vec[1].iov_base = &type;
473 vec[1].iov_len = sizeof(type);
474 vec[2].iov_base = &len;
475 vec[2].iov_len = sizeof(len);
476 vec[3].iov_base = (void*)payload;
477 vec[3].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, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800480}
481
482/*
483 * Like __android_log_security_bwrite, but used for writing strings to the
484 * security log.
485 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800486int __android_log_security_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_SECURITY, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800501}