blob: aef9e04c34271b8fa5048d1fb00e18444c018d8b [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 Salyzyn81321a72017-03-09 07:28:29 -080028#include <log/log_transport.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080029#include <private/android_filesystem_config.h>
30#include <private/android_logger.h>
31
32#include "config_write.h"
33#include "log_portability.h"
34#include "logger.h"
Tom Cherry6f6ef392019-01-16 14:17:08 -080035#include "uio.h"
Mark Salyzyn018a96d2016-03-01 13:45:42 -080036
37#define LOG_BUF_SIZE 1024
38
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080039static int __write_to_log_init(log_id_t, struct iovec* vec, size_t nr);
Tom Cherry71ba1642019-01-10 10:37:36 -080040static int (*write_to_log)(log_id_t, struct iovec* vec, size_t nr) = __write_to_log_init;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080041
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080042static int check_log_uid_permissions() {
Dan Willemsen0910d2d2016-11-29 13:39:55 -080043#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080044 uid_t uid = __android_log_uid();
Mark Salyzync33103c2016-03-28 16:20:29 -070045
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080046 /* Matches clientHasLogCredentials() in logd */
47 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
48 uid = geteuid();
Mark Salyzync33103c2016-03-28 16:20:29 -070049 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080050 gid_t gid = getgid();
51 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
52 gid = getegid();
53 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
54 int num_groups;
55 gid_t* groups;
Mark Salyzync33103c2016-03-28 16:20:29 -070056
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080057 num_groups = getgroups(0, NULL);
58 if (num_groups <= 0) {
59 return -EPERM;
60 }
Tom Cherry71ba1642019-01-10 10:37:36 -080061 groups = static_cast<gid_t*>(calloc(num_groups, sizeof(gid_t)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080062 if (!groups) {
63 return -ENOMEM;
64 }
65 num_groups = getgroups(num_groups, groups);
66 while (num_groups > 0) {
67 if (groups[num_groups - 1] == AID_LOG) {
68 break;
Mark Salyzync33103c2016-03-28 16:20:29 -070069 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080070 --num_groups;
71 }
72 free(groups);
73 if (num_groups <= 0) {
74 return -EPERM;
75 }
Mark Salyzync33103c2016-03-28 16:20:29 -070076 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080077 }
Mark Salyzync33103c2016-03-28 16:20:29 -070078 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080079 }
Mark Salyzync33103c2016-03-28 16:20:29 -070080#endif
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080081 return 0;
Mark Salyzync33103c2016-03-28 16:20:29 -070082}
83
Tom Cherry71ba1642019-01-10 10:37:36 -080084static void __android_log_cache_available(struct android_log_transport_write* node) {
85 uint32_t i;
Mark Salyzync33103c2016-03-28 16:20:29 -070086
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080087 if (node->logMask) {
88 return;
89 }
Mark Salyzync33103c2016-03-28 16:20:29 -070090
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080091 for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
92 if (node->write && (i != LOG_ID_KERNEL) &&
93 ((i != LOG_ID_SECURITY) || (check_log_uid_permissions() == 0)) &&
Tom Cherry71ba1642019-01-10 10:37:36 -080094 (!node->available || ((*node->available)(static_cast<log_id_t>(i)) >= 0))) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080095 node->logMask |= 1 << i;
Mark Salyzync33103c2016-03-28 16:20:29 -070096 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080097 }
Mark Salyzync33103c2016-03-28 16:20:29 -070098}
99
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800100#if defined(__ANDROID__)
Mark Salyzynba1a7982016-09-13 07:28:21 -0700101static atomic_uintptr_t tagMap;
102#endif
103
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700104/*
105 * Release any logger resources. A new log write will immediately re-acquire.
106 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800107void __android_log_close() {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800108 struct android_log_transport_write* transport;
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
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800127 write_transport_for_each(transport, &__android_log_persist_write) {
128 if (transport->close) {
129 (*transport->close)();
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700130 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800131 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700132
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800133 write_transport_for_each(transport, &__android_log_transport_write) {
134 if (transport->close) {
135 (*transport->close)();
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700136 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800137 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700138
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800139 __android_log_config_write_close();
Mark Salyzyn71002882016-03-08 16:18:26 -0800140
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800141#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800142 /*
143 * Additional risk here somewhat mitigated by immediately unlock flushing
144 * the processor cache. The multi-threaded race that we choose to accept,
145 * to minimize locking, is an atomic_load in a writer picking up a value
146 * just prior to entering this routine. There will be an use after free.
147 *
148 * Again, anyone calling this is doing so to release the logging resources
149 * is most probably going to quiesce then shut down; or to restart after
150 * a fork so the risk should be non-existent. For this reason we
151 * choose a mitigation stance for efficiency instead of incuring the cost
152 * of a lock for every log write.
153 */
154 m = (EventTagMap*)atomic_exchange(&tagMap, (uintptr_t)0);
Mark Salyzynba1a7982016-09-13 07:28:21 -0700155#endif
156
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800157 __android_log_unlock();
Mark Salyzynba1a7982016-09-13 07:28:21 -0700158
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800159#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800160 if (m != (EventTagMap*)(uintptr_t)-1LL) android_closeEventTagMap(m);
Mark Salyzynba1a7982016-09-13 07:28:21 -0700161#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700162}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800163
164/* log_init_lock assumed */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800165static int __write_to_log_initialize() {
166 struct android_log_transport_write* transport;
167 struct listnode* n;
168 int i = 0, ret = 0;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800169
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800170 __android_log_config_write();
171 write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
172 __android_log_cache_available(transport);
173 if (!transport->logMask) {
174 list_remove(&transport->node);
175 continue;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800176 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800177 if (!transport->open || ((*transport->open)() < 0)) {
178 if (transport->close) {
179 (*transport->close)();
180 }
181 list_remove(&transport->node);
182 continue;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800183 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800184 ++ret;
185 }
186 write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
187 __android_log_cache_available(transport);
188 if (!transport->logMask) {
189 list_remove(&transport->node);
190 continue;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800191 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800192 if (!transport->open || ((*transport->open)() < 0)) {
193 if (transport->close) {
194 (*transport->close)();
195 }
196 list_remove(&transport->node);
197 continue;
198 }
199 ++i;
200 }
201 if (!ret && !i) {
202 return -ENODEV;
203 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800204
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800205 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800206}
207
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800208static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) {
209 struct android_log_transport_write* node;
Mark Salyzyn72d37242018-03-07 10:42:06 -0800210 int ret, save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800211 struct timespec ts;
212 size_t len, i;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800213
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800214 for (len = i = 0; i < nr; ++i) {
215 len += vec[i].iov_len;
216 }
217 if (!len) {
218 return -EINVAL;
219 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800220
Mark Salyzyn72d37242018-03-07 10:42:06 -0800221 save_errno = errno;
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800222#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800223 clock_gettime(android_log_clockid(), &ts);
Mark Salyzyn142b43d2016-12-28 10:30:57 -0800224
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800225 if (log_id == LOG_ID_SECURITY) {
226 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 ret = check_log_uid_permissions();
232 if (ret < 0) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800233 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800234 return ret;
235 }
236 if (!__android_log_security()) {
237 /* If only we could reset downstream logd counter */
Mark Salyzyn72d37242018-03-07 10:42:06 -0800238 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800239 return -EPERM;
240 }
Yao Chen025f05a2017-12-01 15:48:19 -0800241 } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800242 const char* tag;
243 size_t len;
244 EventTagMap *m, *f;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800245
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800246 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800247 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800248 return -EINVAL;
249 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800250
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800251 tag = NULL;
252 len = 0;
253 f = NULL;
254 m = (EventTagMap*)atomic_load(&tagMap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800255
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800256 if (!m) {
257 ret = __android_log_trylock();
258 m = (EventTagMap*)atomic_load(&tagMap); /* trylock flush cache */
259 if (!m) {
260 m = android_openEventTagMap(NULL);
261 if (ret) { /* trylock failed, use local copy, mark for close */
262 f = m;
263 } else {
264 if (!m) { /* One chance to open map file */
265 m = (EventTagMap*)(uintptr_t)-1LL;
266 }
267 atomic_store(&tagMap, (uintptr_t)m);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800268 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800269 }
270 if (!ret) { /* trylock succeeded, unlock */
271 __android_log_unlock();
272 }
273 }
274 if (m && (m != (EventTagMap*)(uintptr_t)-1LL)) {
Tom Cherry7d045f62019-09-30 12:58:55 -0700275 tag = android_lookupEventTag_len(m, &len, *static_cast<uint32_t*>(vec[0].iov_base));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800276 }
Tom Cherry71ba1642019-01-10 10:37:36 -0800277 ret = __android_log_is_loggable_len(ANDROID_LOG_INFO, tag, len, ANDROID_LOG_VERBOSE);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800278 if (f) { /* local copy marked for close */
279 android_closeEventTagMap(f);
280 }
281 if (!ret) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800282 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800283 return -EPERM;
284 }
285 } else {
286 /* Validate the incoming tag, tag content can not split across iovec */
287 char prio = ANDROID_LOG_VERBOSE;
Tom Cherry71ba1642019-01-10 10:37:36 -0800288 const char* tag = static_cast<const char*>(vec[0].iov_base);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800289 size_t len = vec[0].iov_len;
290 if (!tag) {
291 len = 0;
292 }
293 if (len > 0) {
294 prio = *tag;
295 if (len > 1) {
296 --len;
297 ++tag;
298 } else {
299 len = vec[1].iov_len;
300 tag = ((const char*)vec[1].iov_base);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800301 if (!tag) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800302 len = 0;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800303 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800304 }
305 }
306 /* tag must be nul terminated */
307 if (tag && strnlen(tag, len) >= len) {
308 tag = NULL;
309 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800310
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800311 if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800312 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800313 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800314 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800315 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800316#else
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800317 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
318 {
319 struct timeval tv;
320 gettimeofday(&tv, NULL);
321 ts.tv_sec = tv.tv_sec;
322 ts.tv_nsec = tv.tv_usec * 1000;
323 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800324#endif
325
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800326 ret = 0;
327 i = 1 << log_id;
328 write_transport_for_each(node, &__android_log_transport_write) {
329 if (node->logMask & i) {
330 ssize_t retval;
331 retval = (*node->write)(log_id, &ts, vec, nr);
332 if (ret >= 0) {
333 ret = retval;
334 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800335 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800336 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800337
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800338 write_transport_for_each(node, &__android_log_persist_write) {
339 if (node->logMask & i) {
340 (void)(*node->write)(log_id, &ts, vec, nr);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800341 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800342 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800343
Mark Salyzyn72d37242018-03-07 10:42:06 -0800344 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800345 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800346}
347
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800348static int __write_to_log_init(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800349 int ret, save_errno = errno;
350
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800351 __android_log_lock();
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800352
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800353 if (write_to_log == __write_to_log_init) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800354 ret = __write_to_log_initialize();
355 if (ret < 0) {
356 __android_log_unlock();
357 if (!list_empty(&__android_log_persist_write)) {
358 __write_to_log_daemon(log_id, vec, nr);
359 }
Mark Salyzyn72d37242018-03-07 10:42:06 -0800360 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800361 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800362 }
363
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800364 write_to_log = __write_to_log_daemon;
365 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800366
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800367 __android_log_unlock();
368
Mark Salyzyn72d37242018-03-07 10:42:06 -0800369 ret = write_to_log(log_id, vec, nr);
370 errno = save_errno;
371 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800372}
373
Tom Cherry2d9779e2019-02-08 11:46:19 -0800374int __android_log_write(int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800375 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800376}
377
Tom Cherry2d9779e2019-02-08 11:46:19 -0800378int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800379 if (!tag) tag = "";
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800380
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800381#if __BIONIC__
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800382 if (prio == ANDROID_LOG_FATAL) {
383 android_set_abort_message(msg);
384 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800385#endif
386
Elliott Hughesde3ad1d2015-04-03 13:24:37 -0700387 struct iovec vec[3];
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800388 vec[0].iov_base = (unsigned char*)&prio;
389 vec[0].iov_len = 1;
390 vec[1].iov_base = (void*)tag;
391 vec[1].iov_len = strlen(tag) + 1;
392 vec[2].iov_base = (void*)msg;
393 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800394
Tom Cherry71ba1642019-01-10 10:37:36 -0800395 return write_to_log(static_cast<log_id_t>(bufID), vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800396}
397
Tom Cherry2d9779e2019-02-08 11:46:19 -0800398int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800399 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800400
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800401 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800402
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800403 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800404}
405
Tom Cherry2d9779e2019-02-08 11:46:19 -0800406int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800407 va_list ap;
408 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800409
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800410 va_start(ap, fmt);
411 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
412 va_end(ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800413
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800414 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800415}
416
Tom Cherry2d9779e2019-02-08 11:46:19 -0800417int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800418 va_list ap;
419 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800420
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800421 va_start(ap, fmt);
422 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
423 va_end(ap);
424
425 return __android_log_buf_write(bufID, prio, tag, buf);
426}
427
Tom Cherry2d9779e2019-02-08 11:46:19 -0800428void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800429 char buf[LOG_BUF_SIZE];
430
431 if (fmt) {
432 va_list ap;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800433 va_start(ap, fmt);
434 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
435 va_end(ap);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800436 } else {
437 /* Msg not provided, log condition. N.B. Do not use cond directly as
438 * format string as it could contain spurious '%' syntax (e.g.
439 * "%d" in "blocks%devs == 0").
440 */
441 if (cond)
442 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
443 else
444 strcpy(buf, "Unspecified assertion failed");
445 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800446
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800447 // Log assertion failures to stderr for the benefit of "adb shell" users
448 // and gtests (http://b/23675822).
Tom Cherry6f6ef392019-01-16 14:17:08 -0800449 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
450 TEMP_FAILURE_RETRY(write(2, "\n", 1));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800451
452 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
453 abort(); /* abort so we have a chance to debug the situation */
454 /* NOTREACHED */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800455}
456
Tom Cherry2d9779e2019-02-08 11:46:19 -0800457int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800458 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800459
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800460 vec[0].iov_base = &tag;
461 vec[0].iov_len = sizeof(tag);
462 vec[1].iov_base = (void*)payload;
463 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800464
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800465 return write_to_log(LOG_ID_EVENTS, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800466}
467
Tom Cherry2d9779e2019-02-08 11:46:19 -0800468int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
Stefan Lafon701a0652017-08-24 20:14:06 -0700469 struct iovec vec[2];
470
471 vec[0].iov_base = &tag;
472 vec[0].iov_len = sizeof(tag);
473 vec[1].iov_base = (void*)payload;
474 vec[1].iov_len = len;
475
476 return write_to_log(LOG_ID_STATS, vec, 2);
477}
478
Tom Cherry2d9779e2019-02-08 11:46:19 -0800479int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800480 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800481
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800482 vec[0].iov_base = &tag;
483 vec[0].iov_len = sizeof(tag);
484 vec[1].iov_base = (void*)payload;
485 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800486
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800487 return write_to_log(LOG_ID_SECURITY, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800488}
489
490/*
491 * Like __android_log_bwrite, but takes the type as well. Doesn't work
492 * for the general case where we're generating lists of stuff, but very
493 * handy if we just want to dump an integer into the log.
494 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800495int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800496 struct iovec vec[3];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800497
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800498 vec[0].iov_base = &tag;
499 vec[0].iov_len = sizeof(tag);
500 vec[1].iov_base = &type;
501 vec[1].iov_len = sizeof(type);
502 vec[2].iov_base = (void*)payload;
503 vec[2].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800504
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800505 return write_to_log(LOG_ID_EVENTS, vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800506}
507
508/*
509 * Like __android_log_bwrite, but used for writing strings to the
510 * event log.
511 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800512int __android_log_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800513 struct iovec vec[4];
514 char type = EVENT_TYPE_STRING;
515 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800516
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800517 vec[0].iov_base = &tag;
518 vec[0].iov_len = sizeof(tag);
519 vec[1].iov_base = &type;
520 vec[1].iov_len = sizeof(type);
521 vec[2].iov_base = &len;
522 vec[2].iov_len = sizeof(len);
523 vec[3].iov_base = (void*)payload;
524 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800525
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800526 return write_to_log(LOG_ID_EVENTS, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800527}
528
529/*
530 * Like __android_log_security_bwrite, but used for writing strings to the
531 * security log.
532 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800533int __android_log_security_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800534 struct iovec vec[4];
535 char type = EVENT_TYPE_STRING;
536 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800537
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800538 vec[0].iov_base = &tag;
539 vec[0].iov_len = sizeof(tag);
540 vec[1].iov_base = &type;
541 vec[1].iov_len = sizeof(type);
542 vec[2].iov_base = &len;
543 vec[2].iov_len = sizeof(len);
544 vec[3].iov_base = (void*)payload;
545 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800546
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800547 return write_to_log(LOG_ID_SECURITY, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800548}
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800549
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800550static int __write_to_log_null(log_id_t log_id, struct iovec* vec, size_t nr) {
551 size_t len, i;
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800552
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800553 if ((log_id < LOG_ID_MIN) || (log_id >= LOG_ID_MAX)) {
554 return -EINVAL;
555 }
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800556
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800557 for (len = i = 0; i < nr; ++i) {
558 len += vec[i].iov_len;
559 }
560 if (!len) {
561 return -EINVAL;
562 }
563 return len;
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800564}
565
566/* Following functions need access to our internal write_to_log status */
567
Tom Cherry2d9779e2019-02-08 11:46:19 -0800568int __android_log_transport;
Mark Salyzyn71002882016-03-08 16:18:26 -0800569
Tom Cherry2d9779e2019-02-08 11:46:19 -0800570int android_set_log_transport(int transport_flag) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800571 int retval;
Mark Salyzyn71002882016-03-08 16:18:26 -0800572
Mark Salyzyn81321a72017-03-09 07:28:29 -0800573 if (transport_flag < 0) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800574 return -EINVAL;
575 }
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800576
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800577 retval = LOGGER_NULL;
Mark Salyzyn71002882016-03-08 16:18:26 -0800578
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800579 __android_log_lock();
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800580
Mark Salyzyn81321a72017-03-09 07:28:29 -0800581 if (transport_flag & LOGGER_NULL) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800582 write_to_log = __write_to_log_null;
Mark Salyzyn71002882016-03-08 16:18:26 -0800583
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800584 __android_log_unlock();
585
Mark Salyzyn71002882016-03-08 16:18:26 -0800586 return retval;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800587 }
588
Tom Cherryd1febd32019-01-09 13:35:43 -0800589 __android_log_transport &= LOGGER_LOGD | LOGGER_STDERR;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800590
Tom Cherryd1febd32019-01-09 13:35:43 -0800591 transport_flag &= LOGGER_LOGD | LOGGER_STDERR;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800592
Mark Salyzyn81321a72017-03-09 07:28:29 -0800593 if (__android_log_transport != transport_flag) {
594 __android_log_transport = transport_flag;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800595 __android_log_config_write_close();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800596
597 write_to_log = __write_to_log_init;
598 /* generically we only expect these two values for write_to_log */
Tom Cherry71ba1642019-01-10 10:37:36 -0800599 } else if ((write_to_log != __write_to_log_init) && (write_to_log != __write_to_log_daemon)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800600 write_to_log = __write_to_log_init;
601 }
602
Mark Salyzyn81321a72017-03-09 07:28:29 -0800603 retval = __android_log_transport;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800604
605 __android_log_unlock();
606
607 return retval;
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800608}
609
Tom Cherry2d9779e2019-02-08 11:46:19 -0800610int android_get_log_transport() {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800611 int ret = LOGGER_DEFAULT;
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800612
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800613 __android_log_lock();
614 if (write_to_log == __write_to_log_null) {
615 ret = LOGGER_NULL;
616 } else {
Tom Cherryd1febd32019-01-09 13:35:43 -0800617 __android_log_transport &= LOGGER_LOGD | LOGGER_STDERR;
Mark Salyzyn81321a72017-03-09 07:28:29 -0800618 ret = __android_log_transport;
Tom Cherry71ba1642019-01-10 10:37:36 -0800619 if ((write_to_log != __write_to_log_init) && (write_to_log != __write_to_log_daemon)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800620 ret = -EINVAL;
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800621 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800622 }
623 __android_log_unlock();
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800624
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800625 return ret;
Mark Salyzyn850d06e2015-02-04 12:39:57 -0800626}