blob: 678e8096139694ccb0abe72eb6d63b38f83857cf [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) {
103 if (node->write && (i != LOG_ID_KERNEL) &&
104 ((i != LOG_ID_SECURITY) || (check_log_uid_permissions() == 0)) &&
Tom Cherry71ba1642019-01-10 10:37:36 -0800105 (!node->available || ((*node->available)(static_cast<log_id_t>(i)) >= 0))) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800106 node->logMask |= 1 << i;
Mark Salyzync33103c2016-03-28 16:20:29 -0700107 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800108 }
Mark Salyzync33103c2016-03-28 16:20:29 -0700109}
110
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800111#if defined(__ANDROID__)
Mark Salyzynba1a7982016-09-13 07:28:21 -0700112static atomic_uintptr_t tagMap;
113#endif
114
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700115/*
116 * Release any logger resources. A new log write will immediately re-acquire.
117 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800118void __android_log_close() {
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800119#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800120 EventTagMap* m;
Mark Salyzynba1a7982016-09-13 07:28:21 -0700121#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700122
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800123 __android_log_lock();
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700124
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800125 write_to_log = __write_to_log_init;
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700126
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800127 /*
128 * Threads that are actively writing at this point are not held back
129 * by a lock and are at risk of dropping the messages with a return code
130 * -EBADF. Prefer to return error code than add the overhead of a lock to
131 * each log writing call to guarantee delivery. In addition, anyone
132 * calling this is doing so to release the logging resources and shut down,
133 * for them to do so with outstanding log requests in other threads is a
134 * disengenuous use of this function.
135 */
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700136
Tom Cherry2beabe52019-10-01 13:05:58 -0700137 if (android_log_write != nullptr) {
138 android_log_write->close();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800139 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700140
Tom Cherry2beabe52019-10-01 13:05:58 -0700141 if (android_log_persist_write != nullptr) {
142 android_log_persist_write->close();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800143 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700144
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800145#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800146 /*
147 * Additional risk here somewhat mitigated by immediately unlock flushing
148 * the processor cache. The multi-threaded race that we choose to accept,
149 * to minimize locking, is an atomic_load in a writer picking up a value
150 * just prior to entering this routine. There will be an use after free.
151 *
152 * Again, anyone calling this is doing so to release the logging resources
153 * is most probably going to quiesce then shut down; or to restart after
154 * a fork so the risk should be non-existent. For this reason we
155 * choose a mitigation stance for efficiency instead of incuring the cost
156 * of a lock for every log write.
157 */
158 m = (EventTagMap*)atomic_exchange(&tagMap, (uintptr_t)0);
Mark Salyzynba1a7982016-09-13 07:28:21 -0700159#endif
160
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800161 __android_log_unlock();
Mark Salyzynba1a7982016-09-13 07:28:21 -0700162
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800163#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800164 if (m != (EventTagMap*)(uintptr_t)-1LL) android_closeEventTagMap(m);
Mark Salyzynba1a7982016-09-13 07:28:21 -0700165#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700166}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800167
Tom Cherry2beabe52019-10-01 13:05:58 -0700168static bool transport_initialize(android_log_transport_write* transport) {
169 if (transport == nullptr) {
170 return false;
171 }
172
173 __android_log_cache_available(transport);
174 if (!transport->logMask) {
175 return false;
176 }
177
178 // TODO: Do we actually need to call close() if open() fails?
179 if (transport->open() < 0) {
180 transport->close();
181 return false;
182 }
183
184 return true;
185}
186
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800187/* log_init_lock assumed */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800188static int __write_to_log_initialize() {
Tom Cherry2beabe52019-10-01 13:05:58 -0700189 if (!transport_initialize(android_log_write)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800190 return -ENODEV;
191 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800192
Tom Cherry97ec4ee2019-10-02 10:52:55 -0700193 transport_initialize(android_log_persist_write);
Tom Cherry2beabe52019-10-01 13:05:58 -0700194
195 return 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800196}
197
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800198static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800199 int ret, save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800200 struct timespec ts;
201 size_t len, i;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800202
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800203 for (len = i = 0; i < nr; ++i) {
204 len += vec[i].iov_len;
205 }
206 if (!len) {
207 return -EINVAL;
208 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800209
Mark Salyzyn72d37242018-03-07 10:42:06 -0800210 save_errno = errno;
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800211#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800212 clock_gettime(android_log_clockid(), &ts);
Mark Salyzyn142b43d2016-12-28 10:30:57 -0800213
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800214 if (log_id == LOG_ID_SECURITY) {
215 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800216 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800217 return -EINVAL;
218 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800219
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800220 ret = check_log_uid_permissions();
221 if (ret < 0) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800222 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800223 return ret;
224 }
225 if (!__android_log_security()) {
226 /* If only we could reset downstream logd counter */
Mark Salyzyn72d37242018-03-07 10:42:06 -0800227 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800228 return -EPERM;
229 }
Yao Chen025f05a2017-12-01 15:48:19 -0800230 } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800231 const char* tag;
232 size_t len;
233 EventTagMap *m, *f;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800234
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800235 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800236 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800237 return -EINVAL;
238 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800239
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800240 tag = NULL;
241 len = 0;
242 f = NULL;
243 m = (EventTagMap*)atomic_load(&tagMap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800244
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800245 if (!m) {
246 ret = __android_log_trylock();
247 m = (EventTagMap*)atomic_load(&tagMap); /* trylock flush cache */
248 if (!m) {
249 m = android_openEventTagMap(NULL);
250 if (ret) { /* trylock failed, use local copy, mark for close */
251 f = m;
252 } else {
253 if (!m) { /* One chance to open map file */
254 m = (EventTagMap*)(uintptr_t)-1LL;
255 }
256 atomic_store(&tagMap, (uintptr_t)m);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800257 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800258 }
259 if (!ret) { /* trylock succeeded, unlock */
260 __android_log_unlock();
261 }
262 }
263 if (m && (m != (EventTagMap*)(uintptr_t)-1LL)) {
Tom Cherry7d045f62019-09-30 12:58:55 -0700264 tag = android_lookupEventTag_len(m, &len, *static_cast<uint32_t*>(vec[0].iov_base));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800265 }
Tom Cherry71ba1642019-01-10 10:37:36 -0800266 ret = __android_log_is_loggable_len(ANDROID_LOG_INFO, tag, len, ANDROID_LOG_VERBOSE);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800267 if (f) { /* local copy marked for close */
268 android_closeEventTagMap(f);
269 }
270 if (!ret) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800271 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800272 return -EPERM;
273 }
274 } else {
Tom Cherry2187a412019-10-01 17:13:43 -0700275 int prio = *static_cast<int*>(vec[0].iov_base);
276 const char* tag = static_cast<const char*>(vec[1].iov_base);
277 size_t len = vec[1].iov_len;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800278 /* tag must be nul terminated */
Tom Cherry2187a412019-10-01 17:13:43 -0700279 if (strnlen(tag, len) >= len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800280 tag = NULL;
281 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800282
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800283 if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800284 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800285 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800286 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800287 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800288#else
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800289 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
290 {
291 struct timeval tv;
292 gettimeofday(&tv, NULL);
293 ts.tv_sec = tv.tv_sec;
294 ts.tv_nsec = tv.tv_usec * 1000;
295 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800296#endif
297
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800298 ret = 0;
299 i = 1 << log_id;
Tom Cherry2beabe52019-10-01 13:05:58 -0700300
301 if (android_log_write != nullptr && (android_log_write->logMask & i)) {
302 ssize_t retval;
303 retval = android_log_write->write(log_id, &ts, vec, nr);
304 if (ret >= 0) {
305 ret = retval;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800306 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800307 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800308
Tom Cherry2beabe52019-10-01 13:05:58 -0700309 if (android_log_persist_write != nullptr && (android_log_persist_write->logMask & i)) {
310 android_log_persist_write->write(log_id, &ts, vec, nr);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800311 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800312
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 -0800317static int __write_to_log_init(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800318 int ret, save_errno = errno;
319
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800320 __android_log_lock();
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800321
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800322 if (write_to_log == __write_to_log_init) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800323 ret = __write_to_log_initialize();
324 if (ret < 0) {
325 __android_log_unlock();
Mark Salyzyn72d37242018-03-07 10:42:06 -0800326 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800327 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800328 }
329
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800330 write_to_log = __write_to_log_daemon;
331 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800332
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800333 __android_log_unlock();
334
Mark Salyzyn72d37242018-03-07 10:42:06 -0800335 ret = write_to_log(log_id, vec, nr);
336 errno = save_errno;
337 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800338}
339
Tom Cherry2d9779e2019-02-08 11:46:19 -0800340int __android_log_write(int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800341 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800342}
343
Tom Cherry2d9779e2019-02-08 11:46:19 -0800344int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800345 if (!tag) tag = "";
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800346
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800347#if __BIONIC__
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800348 if (prio == ANDROID_LOG_FATAL) {
349 android_set_abort_message(msg);
350 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800351#endif
352
Elliott Hughesde3ad1d2015-04-03 13:24:37 -0700353 struct iovec vec[3];
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800354 vec[0].iov_base = (unsigned char*)&prio;
355 vec[0].iov_len = 1;
356 vec[1].iov_base = (void*)tag;
357 vec[1].iov_len = strlen(tag) + 1;
358 vec[2].iov_base = (void*)msg;
359 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800360
Tom Cherry71ba1642019-01-10 10:37:36 -0800361 return write_to_log(static_cast<log_id_t>(bufID), vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800362}
363
Tom Cherry2d9779e2019-02-08 11:46:19 -0800364int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800365 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800366
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800367 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800368
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800369 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800370}
371
Tom Cherry2d9779e2019-02-08 11:46:19 -0800372int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800373 va_list ap;
374 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800375
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800376 va_start(ap, fmt);
377 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
378 va_end(ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800379
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800380 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800381}
382
Tom Cherry2d9779e2019-02-08 11:46:19 -0800383int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800384 va_list ap;
385 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800386
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800387 va_start(ap, fmt);
388 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
389 va_end(ap);
390
391 return __android_log_buf_write(bufID, prio, tag, buf);
392}
393
Tom Cherry2d9779e2019-02-08 11:46:19 -0800394void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800395 char buf[LOG_BUF_SIZE];
396
397 if (fmt) {
398 va_list ap;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800399 va_start(ap, fmt);
400 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
401 va_end(ap);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800402 } else {
403 /* Msg not provided, log condition. N.B. Do not use cond directly as
404 * format string as it could contain spurious '%' syntax (e.g.
405 * "%d" in "blocks%devs == 0").
406 */
407 if (cond)
408 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
409 else
410 strcpy(buf, "Unspecified assertion failed");
411 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800412
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800413 // Log assertion failures to stderr for the benefit of "adb shell" users
414 // and gtests (http://b/23675822).
Tom Cherry6f6ef392019-01-16 14:17:08 -0800415 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
416 TEMP_FAILURE_RETRY(write(2, "\n", 1));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800417
418 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
419 abort(); /* abort so we have a chance to debug the situation */
420 /* NOTREACHED */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800421}
422
Tom Cherry2d9779e2019-02-08 11:46:19 -0800423int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800424 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800425
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800426 vec[0].iov_base = &tag;
427 vec[0].iov_len = sizeof(tag);
428 vec[1].iov_base = (void*)payload;
429 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800430
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800431 return write_to_log(LOG_ID_EVENTS, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800432}
433
Tom Cherry2d9779e2019-02-08 11:46:19 -0800434int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
Stefan Lafon701a0652017-08-24 20:14:06 -0700435 struct iovec vec[2];
436
437 vec[0].iov_base = &tag;
438 vec[0].iov_len = sizeof(tag);
439 vec[1].iov_base = (void*)payload;
440 vec[1].iov_len = len;
441
442 return write_to_log(LOG_ID_STATS, vec, 2);
443}
444
Tom Cherry2d9779e2019-02-08 11:46:19 -0800445int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800446 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800447
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800448 vec[0].iov_base = &tag;
449 vec[0].iov_len = sizeof(tag);
450 vec[1].iov_base = (void*)payload;
451 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800452
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800453 return write_to_log(LOG_ID_SECURITY, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800454}
455
456/*
457 * Like __android_log_bwrite, but takes the type as well. Doesn't work
458 * for the general case where we're generating lists of stuff, but very
459 * handy if we just want to dump an integer into the log.
460 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800461int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800462 struct iovec vec[3];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800463
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800464 vec[0].iov_base = &tag;
465 vec[0].iov_len = sizeof(tag);
466 vec[1].iov_base = &type;
467 vec[1].iov_len = sizeof(type);
468 vec[2].iov_base = (void*)payload;
469 vec[2].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800470
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800471 return write_to_log(LOG_ID_EVENTS, vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800472}
473
474/*
475 * Like __android_log_bwrite, but used for writing strings to the
476 * event log.
477 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800478int __android_log_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800479 struct iovec vec[4];
480 char type = EVENT_TYPE_STRING;
481 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800482
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800483 vec[0].iov_base = &tag;
484 vec[0].iov_len = sizeof(tag);
485 vec[1].iov_base = &type;
486 vec[1].iov_len = sizeof(type);
487 vec[2].iov_base = &len;
488 vec[2].iov_len = sizeof(len);
489 vec[3].iov_base = (void*)payload;
490 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800491
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800492 return write_to_log(LOG_ID_EVENTS, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800493}
494
495/*
496 * Like __android_log_security_bwrite, but used for writing strings to the
497 * security log.
498 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800499int __android_log_security_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800500 struct iovec vec[4];
501 char type = EVENT_TYPE_STRING;
502 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800503
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800504 vec[0].iov_base = &tag;
505 vec[0].iov_len = sizeof(tag);
506 vec[1].iov_base = &type;
507 vec[1].iov_len = sizeof(type);
508 vec[2].iov_base = &len;
509 vec[2].iov_len = sizeof(len);
510 vec[3].iov_base = (void*)payload;
511 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800512
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800513 return write_to_log(LOG_ID_SECURITY, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800514}