blob: 85475ec0eca6fb8a94e827ec663f90975c139150 [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
Mark Salyzyn018a96d2016-03-01 13:45:42 -080027#include <private/android_filesystem_config.h>
28#include <private/android_logger.h>
29
Mark Salyzyn018a96d2016-03-01 13:45:42 -080030#include "log_portability.h"
31#include "logger.h"
Tom Cherry6f6ef392019-01-16 14:17:08 -080032#include "uio.h"
Mark Salyzyn018a96d2016-03-01 13:45:42 -080033
34#define LOG_BUF_SIZE 1024
35
Tom Cherry97ec4ee2019-10-02 10:52:55 -070036#if (FAKE_LOG_DEVICE == 0)
37extern struct android_log_transport_write logdLoggerWrite;
38extern struct android_log_transport_write pmsgLoggerWrite;
39
40android_log_transport_write* android_log_write = &logdLoggerWrite;
41android_log_transport_write* android_log_persist_write = &pmsgLoggerWrite;
42#else
43extern android_log_transport_write fakeLoggerWrite;
44
45android_log_transport_write* android_log_write = &fakeLoggerWrite;
Tom Cherry2beabe52019-10-01 13:05:58 -070046android_log_transport_write* android_log_persist_write = nullptr;
Tom Cherry97ec4ee2019-10-02 10:52:55 -070047#endif
Tom Cherry2beabe52019-10-01 13:05:58 -070048
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080049static int __write_to_log_init(log_id_t, struct iovec* vec, size_t nr);
Tom Cherry71ba1642019-01-10 10:37:36 -080050static int (*write_to_log)(log_id_t, struct iovec* vec, size_t nr) = __write_to_log_init;
Mark Salyzyn018a96d2016-03-01 13:45:42 -080051
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080052static int check_log_uid_permissions() {
Dan Willemsen0910d2d2016-11-29 13:39:55 -080053#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080054 uid_t uid = __android_log_uid();
Mark Salyzync33103c2016-03-28 16:20:29 -070055
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080056 /* Matches clientHasLogCredentials() in logd */
57 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
58 uid = geteuid();
Mark Salyzync33103c2016-03-28 16:20:29 -070059 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080060 gid_t gid = getgid();
61 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
62 gid = getegid();
63 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
64 int num_groups;
65 gid_t* groups;
Mark Salyzync33103c2016-03-28 16:20:29 -070066
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080067 num_groups = getgroups(0, NULL);
68 if (num_groups <= 0) {
69 return -EPERM;
70 }
Tom Cherry71ba1642019-01-10 10:37:36 -080071 groups = static_cast<gid_t*>(calloc(num_groups, sizeof(gid_t)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080072 if (!groups) {
73 return -ENOMEM;
74 }
75 num_groups = getgroups(num_groups, groups);
76 while (num_groups > 0) {
77 if (groups[num_groups - 1] == AID_LOG) {
78 break;
Mark Salyzync33103c2016-03-28 16:20:29 -070079 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080080 --num_groups;
81 }
82 free(groups);
83 if (num_groups <= 0) {
84 return -EPERM;
85 }
Mark Salyzync33103c2016-03-28 16:20:29 -070086 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080087 }
Mark Salyzync33103c2016-03-28 16:20:29 -070088 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080089 }
Mark Salyzync33103c2016-03-28 16:20:29 -070090#endif
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080091 return 0;
Mark Salyzync33103c2016-03-28 16:20:29 -070092}
93
Tom Cherry71ba1642019-01-10 10:37:36 -080094static void __android_log_cache_available(struct android_log_transport_write* node) {
95 uint32_t i;
Mark Salyzync33103c2016-03-28 16:20:29 -070096
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080097 if (node->logMask) {
98 return;
99 }
Mark Salyzync33103c2016-03-28 16:20:29 -0700100
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800101 for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
Tom Cherry990852f2019-10-02 10:34:03 -0700102 if (i != LOG_ID_KERNEL && (i != LOG_ID_SECURITY || check_log_uid_permissions() == 0) &&
103 (*node->available)(static_cast<log_id_t>(i)) >= 0) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800104 node->logMask |= 1 << i;
Mark Salyzync33103c2016-03-28 16:20:29 -0700105 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800106 }
Mark Salyzync33103c2016-03-28 16:20:29 -0700107}
108
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700109/*
110 * Release any logger resources. A new log write will immediately re-acquire.
111 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800112void __android_log_close() {
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
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800135 __android_log_unlock();
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700136}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800137
Tom Cherry2beabe52019-10-01 13:05:58 -0700138static bool transport_initialize(android_log_transport_write* transport) {
139 if (transport == nullptr) {
140 return false;
141 }
142
143 __android_log_cache_available(transport);
144 if (!transport->logMask) {
145 return false;
146 }
147
148 // TODO: Do we actually need to call close() if open() fails?
149 if (transport->open() < 0) {
150 transport->close();
151 return false;
152 }
153
154 return true;
155}
156
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800157/* log_init_lock assumed */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800158static int __write_to_log_initialize() {
Tom Cherry2beabe52019-10-01 13:05:58 -0700159 if (!transport_initialize(android_log_write)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800160 return -ENODEV;
161 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800162
Tom Cherry97ec4ee2019-10-02 10:52:55 -0700163 transport_initialize(android_log_persist_write);
Tom Cherry2beabe52019-10-01 13:05:58 -0700164
165 return 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800166}
167
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800168static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800169 int ret, save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800170 struct timespec ts;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800171
Mark Salyzyn72d37242018-03-07 10:42:06 -0800172 save_errno = errno;
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800173#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800174 clock_gettime(android_log_clockid(), &ts);
Mark Salyzyn142b43d2016-12-28 10:30:57 -0800175
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800176 if (log_id == LOG_ID_SECURITY) {
177 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800178 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800179 return -EINVAL;
180 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800181
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800182 ret = check_log_uid_permissions();
183 if (ret < 0) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800184 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800185 return ret;
186 }
187 if (!__android_log_security()) {
188 /* If only we could reset downstream logd counter */
Mark Salyzyn72d37242018-03-07 10:42:06 -0800189 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800190 return -EPERM;
191 }
Yao Chen025f05a2017-12-01 15:48:19 -0800192 } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800193 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800194 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800195 return -EINVAL;
196 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800197 } else {
Tom Cherry2187a412019-10-01 17:13:43 -0700198 int prio = *static_cast<int*>(vec[0].iov_base);
199 const char* tag = static_cast<const char*>(vec[1].iov_base);
200 size_t len = vec[1].iov_len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800201
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800202 if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800203 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800204 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800205 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800206 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800207#else
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800208 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
209 {
210 struct timeval tv;
211 gettimeofday(&tv, NULL);
212 ts.tv_sec = tv.tv_sec;
213 ts.tv_nsec = tv.tv_usec * 1000;
214 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800215#endif
216
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800217 ret = 0;
Tom Cherry990852f2019-10-02 10:34:03 -0700218 size_t i = 1 << log_id;
Tom Cherry2beabe52019-10-01 13:05:58 -0700219
220 if (android_log_write != nullptr && (android_log_write->logMask & i)) {
221 ssize_t retval;
222 retval = android_log_write->write(log_id, &ts, vec, nr);
223 if (ret >= 0) {
224 ret = retval;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800225 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800226 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800227
Tom Cherry2beabe52019-10-01 13:05:58 -0700228 if (android_log_persist_write != nullptr && (android_log_persist_write->logMask & i)) {
229 android_log_persist_write->write(log_id, &ts, vec, nr);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800230 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800231
Mark Salyzyn72d37242018-03-07 10:42:06 -0800232 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800233 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800234}
235
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800236static int __write_to_log_init(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800237 int ret, save_errno = errno;
238
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800239 __android_log_lock();
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800240
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800241 if (write_to_log == __write_to_log_init) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800242 ret = __write_to_log_initialize();
243 if (ret < 0) {
244 __android_log_unlock();
Mark Salyzyn72d37242018-03-07 10:42:06 -0800245 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800246 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800247 }
248
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800249 write_to_log = __write_to_log_daemon;
250 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800251
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800252 __android_log_unlock();
253
Mark Salyzyn72d37242018-03-07 10:42:06 -0800254 ret = write_to_log(log_id, vec, nr);
255 errno = save_errno;
256 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800257}
258
Tom Cherry2d9779e2019-02-08 11:46:19 -0800259int __android_log_write(int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800260 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800261}
262
Tom Cherry2d9779e2019-02-08 11:46:19 -0800263int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800264 if (!tag) tag = "";
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800265
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800266#if __BIONIC__
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800267 if (prio == ANDROID_LOG_FATAL) {
268 android_set_abort_message(msg);
269 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800270#endif
271
Elliott Hughesde3ad1d2015-04-03 13:24:37 -0700272 struct iovec vec[3];
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800273 vec[0].iov_base = (unsigned char*)&prio;
274 vec[0].iov_len = 1;
275 vec[1].iov_base = (void*)tag;
276 vec[1].iov_len = strlen(tag) + 1;
277 vec[2].iov_base = (void*)msg;
278 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800279
Tom Cherry71ba1642019-01-10 10:37:36 -0800280 return write_to_log(static_cast<log_id_t>(bufID), vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800281}
282
Tom Cherry2d9779e2019-02-08 11:46:19 -0800283int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800284 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800285
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800286 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800287
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800288 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800289}
290
Tom Cherry2d9779e2019-02-08 11:46:19 -0800291int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800292 va_list ap;
293 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800294
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800295 va_start(ap, fmt);
296 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
297 va_end(ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800298
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800299 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800300}
301
Tom Cherry2d9779e2019-02-08 11:46:19 -0800302int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800303 va_list ap;
304 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800305
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800306 va_start(ap, fmt);
307 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
308 va_end(ap);
309
310 return __android_log_buf_write(bufID, prio, tag, buf);
311}
312
Tom Cherry2d9779e2019-02-08 11:46:19 -0800313void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800314 char buf[LOG_BUF_SIZE];
315
316 if (fmt) {
317 va_list ap;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800318 va_start(ap, fmt);
319 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
320 va_end(ap);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800321 } else {
322 /* Msg not provided, log condition. N.B. Do not use cond directly as
323 * format string as it could contain spurious '%' syntax (e.g.
324 * "%d" in "blocks%devs == 0").
325 */
326 if (cond)
327 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
328 else
329 strcpy(buf, "Unspecified assertion failed");
330 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800331
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800332 // Log assertion failures to stderr for the benefit of "adb shell" users
333 // and gtests (http://b/23675822).
Tom Cherry6f6ef392019-01-16 14:17:08 -0800334 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
335 TEMP_FAILURE_RETRY(write(2, "\n", 1));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800336
337 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
338 abort(); /* abort so we have a chance to debug the situation */
339 /* NOTREACHED */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800340}
341
Tom Cherry2d9779e2019-02-08 11:46:19 -0800342int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800343 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800344
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800345 vec[0].iov_base = &tag;
346 vec[0].iov_len = sizeof(tag);
347 vec[1].iov_base = (void*)payload;
348 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800349
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800350 return write_to_log(LOG_ID_EVENTS, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800351}
352
Tom Cherry2d9779e2019-02-08 11:46:19 -0800353int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
Stefan Lafon701a0652017-08-24 20:14:06 -0700354 struct iovec vec[2];
355
356 vec[0].iov_base = &tag;
357 vec[0].iov_len = sizeof(tag);
358 vec[1].iov_base = (void*)payload;
359 vec[1].iov_len = len;
360
361 return write_to_log(LOG_ID_STATS, vec, 2);
362}
363
Tom Cherry2d9779e2019-02-08 11:46:19 -0800364int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800365 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800366
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800367 vec[0].iov_base = &tag;
368 vec[0].iov_len = sizeof(tag);
369 vec[1].iov_base = (void*)payload;
370 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800371
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800372 return write_to_log(LOG_ID_SECURITY, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800373}
374
375/*
376 * Like __android_log_bwrite, but takes the type as well. Doesn't work
377 * for the general case where we're generating lists of stuff, but very
378 * handy if we just want to dump an integer into the log.
379 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800380int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800381 struct iovec vec[3];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800382
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800383 vec[0].iov_base = &tag;
384 vec[0].iov_len = sizeof(tag);
385 vec[1].iov_base = &type;
386 vec[1].iov_len = sizeof(type);
387 vec[2].iov_base = (void*)payload;
388 vec[2].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800389
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800390 return write_to_log(LOG_ID_EVENTS, vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800391}
392
393/*
394 * Like __android_log_bwrite, but used for writing strings to the
395 * event log.
396 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800397int __android_log_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800398 struct iovec vec[4];
399 char type = EVENT_TYPE_STRING;
400 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800401
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800402 vec[0].iov_base = &tag;
403 vec[0].iov_len = sizeof(tag);
404 vec[1].iov_base = &type;
405 vec[1].iov_len = sizeof(type);
406 vec[2].iov_base = &len;
407 vec[2].iov_len = sizeof(len);
408 vec[3].iov_base = (void*)payload;
409 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800410
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800411 return write_to_log(LOG_ID_EVENTS, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800412}
413
414/*
415 * Like __android_log_security_bwrite, but used for writing strings to the
416 * security log.
417 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800418int __android_log_security_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800419 struct iovec vec[4];
420 char type = EVENT_TYPE_STRING;
421 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800422
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800423 vec[0].iov_base = &tag;
424 vec[0].iov_len = sizeof(tag);
425 vec[1].iov_base = &type;
426 vec[1].iov_len = sizeof(type);
427 vec[2].iov_base = &len;
428 vec[2].iov_len = sizeof(len);
429 vec[3].iov_base = (void*)payload;
430 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800431
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800432 return write_to_log(LOG_ID_SECURITY, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800433}