blob: ca68296633fa5e280a930825ed42337cf0e7f902 [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
Tom Cherry2ec6a532020-01-27 08:35:13 -080017#include "logger_write.h"
18
Mark Salyzyn018a96d2016-03-01 13:45:42 -080019#include <errno.h>
Tom Cherry349b0c42020-01-08 14:47:42 -080020#include <inttypes.h>
Tom Cherry69ee5dd2020-01-22 07:48:42 -080021#include <libgen.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080022#include <stdlib.h>
23#include <string.h>
24#include <sys/time.h>
25
26#ifdef __BIONIC__
27#include <android/set_abort_message.h>
28#endif
29
Tom Cherry349b0c42020-01-08 14:47:42 -080030#include <shared_mutex>
31
Tom Cherryff464b12020-01-27 13:49:26 -080032#include <android-base/errno_restorer.h>
Tom Cherry121292d2020-01-14 09:52:10 -080033#include <android-base/macros.h>
Mark Salyzyn018a96d2016-03-01 13:45:42 -080034#include <private/android_filesystem_config.h>
35#include <private/android_logger.h>
36
Tom Cherry349b0c42020-01-08 14:47:42 -080037#include "android/log.h"
Tom Cherry69ee5dd2020-01-22 07:48:42 -080038#include "log/log_read.h"
Mark Salyzyn018a96d2016-03-01 13:45:42 -080039#include "logger.h"
Tom Cherry349b0c42020-01-08 14:47:42 -080040#include "rwlock.h"
Tom Cherry6f6ef392019-01-16 14:17:08 -080041#include "uio.h"
Mark Salyzyn018a96d2016-03-01 13:45:42 -080042
Tom Cherry97ec4ee2019-10-02 10:52:55 -070043#if (FAKE_LOG_DEVICE == 0)
Tom Cherry21bb36c2020-01-08 15:18:26 -080044#include "logd_writer.h"
45#include "pmsg_writer.h"
Tom Cherry97ec4ee2019-10-02 10:52:55 -070046#else
Tom Cherry21bb36c2020-01-08 15:18:26 -080047#include "fake_log_device.h"
Tom Cherry97ec4ee2019-10-02 10:52:55 -070048#endif
Tom Cherry2beabe52019-10-01 13:05:58 -070049
Tom Cherry349b0c42020-01-08 14:47:42 -080050#if defined(__APPLE__)
51#include <pthread.h>
52#elif defined(__linux__) && !defined(__ANDROID__)
53#include <syscall.h>
54#elif defined(_WIN32)
55#include <windows.h>
56#endif
57
Tom Cherryff464b12020-01-27 13:49:26 -080058using android::base::ErrnoRestorer;
59
Tom Cherry21bb36c2020-01-08 15:18:26 -080060#define LOG_BUF_SIZE 1024
61
Dan Willemsen0910d2d2016-11-29 13:39:55 -080062#if defined(__ANDROID__)
Tom Cherry06e0fce2019-12-11 14:26:37 -080063static int check_log_uid_permissions() {
Tom Cherryb47aa2a2020-01-08 15:34:14 -080064 uid_t uid = getuid();
Mark Salyzync33103c2016-03-28 16:20:29 -070065
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080066 /* Matches clientHasLogCredentials() in logd */
67 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
68 uid = geteuid();
Mark Salyzync33103c2016-03-28 16:20:29 -070069 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080070 gid_t gid = getgid();
71 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
72 gid = getegid();
73 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
74 int num_groups;
75 gid_t* groups;
Mark Salyzync33103c2016-03-28 16:20:29 -070076
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080077 num_groups = getgroups(0, NULL);
78 if (num_groups <= 0) {
79 return -EPERM;
80 }
Tom Cherry71ba1642019-01-10 10:37:36 -080081 groups = static_cast<gid_t*>(calloc(num_groups, sizeof(gid_t)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080082 if (!groups) {
83 return -ENOMEM;
84 }
85 num_groups = getgroups(num_groups, groups);
86 while (num_groups > 0) {
87 if (groups[num_groups - 1] == AID_LOG) {
88 break;
Mark Salyzync33103c2016-03-28 16:20:29 -070089 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080090 --num_groups;
91 }
92 free(groups);
93 if (num_groups <= 0) {
94 return -EPERM;
95 }
Mark Salyzync33103c2016-03-28 16:20:29 -070096 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080097 }
Mark Salyzync33103c2016-03-28 16:20:29 -070098 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080099 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800100 return 0;
Mark Salyzync33103c2016-03-28 16:20:29 -0700101}
Tom Cherry06e0fce2019-12-11 14:26:37 -0800102#endif
Mark Salyzync33103c2016-03-28 16:20:29 -0700103
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() {
Tom Cherry21bb36c2020-01-08 15:18:26 -0800108#if (FAKE_LOG_DEVICE == 0)
109 LogdClose();
110 PmsgClose();
111#else
112 FakeClose();
113#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700114}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800115
Tom Cherry69ee5dd2020-01-22 07:48:42 -0800116#if defined(__GLIBC__) || defined(_WIN32)
117static const char* getprogname() {
118#if defined(__GLIBC__)
119 return program_invocation_short_name;
120#elif defined(_WIN32)
121 static bool first = true;
122 static char progname[MAX_PATH] = {};
123
124 if (first) {
125 char path[PATH_MAX + 1];
126 DWORD result = GetModuleFileName(nullptr, path, sizeof(path) - 1);
127 if (result == 0 || result == sizeof(path) - 1) return "";
128 path[PATH_MAX - 1] = 0;
129
130 char* path_basename = basename(path);
131
132 snprintf(progname, sizeof(progname), "%s", path_basename);
133 first = false;
134 }
135
136 return progname;
137#endif
138}
139#endif
140
141// It's possible for logging to happen during static initialization before our globals are
142// initialized, so we place this std::string in a function such that it is initialized on the first
143// call.
Tom Cherry2ec6a532020-01-27 08:35:13 -0800144std::string& GetDefaultTag() {
Tom Cherry69ee5dd2020-01-22 07:48:42 -0800145 static std::string default_tag = getprogname();
146 return default_tag;
147}
Tom Cherry2ec6a532020-01-27 08:35:13 -0800148RwLock default_tag_lock;
Tom Cherry69ee5dd2020-01-22 07:48:42 -0800149
150void __android_log_set_default_tag(const char* tag) {
151 auto lock = std::unique_lock{default_tag_lock};
152 GetDefaultTag().assign(tag, 0, LOGGER_ENTRY_MAX_PAYLOAD);
153}
154
Tom Cherry0391a872020-01-16 15:58:02 -0800155static int minimum_log_priority = ANDROID_LOG_DEFAULT;
156int __android_log_set_minimum_priority(int priority) {
157 int old_minimum_log_priority = minimum_log_priority;
158 minimum_log_priority = priority;
159 return old_minimum_log_priority;
160}
161
162int __android_log_get_minimum_priority() {
163 return minimum_log_priority;
164}
165
Tom Cherry349b0c42020-01-08 14:47:42 -0800166#ifdef __ANDROID__
167static __android_logger_function logger_function = __android_log_logd_logger;
168#else
169static __android_logger_function logger_function = __android_log_stderr_logger;
170#endif
171static RwLock logger_function_lock;
172
173void __android_log_set_logger(__android_logger_function logger) {
174 auto lock = std::unique_lock{logger_function_lock};
175 logger_function = logger;
176}
177
178void __android_log_default_aborter(const char* abort_message) {
179#ifdef __ANDROID__
180 android_set_abort_message(abort_message);
181#else
182 UNUSED(abort_message);
183#endif
184 abort();
185}
186
187static __android_aborter_function aborter_function = __android_log_default_aborter;
188static RwLock aborter_function_lock;
189
190void __android_log_set_aborter(__android_aborter_function aborter) {
191 auto lock = std::unique_lock{aborter_function_lock};
192 aborter_function = aborter;
193}
194
195void __android_log_call_aborter(const char* abort_message) {
196 auto lock = std::shared_lock{aborter_function_lock};
197 aborter_function(abort_message);
198}
199
200#ifdef __ANDROID__
Tom Cherry06e0fce2019-12-11 14:26:37 -0800201static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr) {
Tom Cherryff464b12020-01-27 13:49:26 -0800202 int ret;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800203 struct timespec ts;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800204
Tom Cherry06e0fce2019-12-11 14:26:37 -0800205 if (log_id == LOG_ID_KERNEL) {
206 return -EINVAL;
207 }
208
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800209 clock_gettime(android_log_clockid(), &ts);
Mark Salyzyn142b43d2016-12-28 10:30:57 -0800210
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800211 if (log_id == LOG_ID_SECURITY) {
212 if (vec[0].iov_len < 4) {
213 return -EINVAL;
214 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800215
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800216 ret = check_log_uid_permissions();
217 if (ret < 0) {
218 return ret;
219 }
220 if (!__android_log_security()) {
221 /* If only we could reset downstream logd counter */
222 return -EPERM;
223 }
Yao Chen025f05a2017-12-01 15:48:19 -0800224 } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800225 if (vec[0].iov_len < 4) {
226 return -EINVAL;
227 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800228 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800229
Tom Cherry21bb36c2020-01-08 15:18:26 -0800230 ret = LogdWrite(log_id, &ts, vec, nr);
231 PmsgWrite(log_id, &ts, vec, nr);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800232
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800233 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800234}
Tom Cherry349b0c42020-01-08 14:47:42 -0800235#else
236static int write_to_log(log_id_t, struct iovec*, size_t) {
237 // Non-Android text logs should go to __android_log_stderr_logger, not here.
238 // Non-Android binary logs are always dropped.
239 return 1;
240}
241#endif
242
243// Copied from base/threads.cpp
244static uint64_t GetThreadId() {
245#if defined(__BIONIC__)
246 return gettid();
247#elif defined(__APPLE__)
248 uint64_t tid;
249 pthread_threadid_np(NULL, &tid);
250 return tid;
251#elif defined(__linux__)
252 return syscall(__NR_gettid);
253#elif defined(_WIN32)
254 return GetCurrentThreadId();
255#endif
256}
257
258void __android_log_stderr_logger(const struct __android_logger_data* logger_data,
259 const char* message) {
260 struct tm now;
261 time_t t = time(nullptr);
262
263#if defined(_WIN32)
264 localtime_s(&now, &t);
265#else
266 localtime_r(&t, &now);
267#endif
268
269 char timestamp[32];
270 strftime(timestamp, sizeof(timestamp), "%m-%d %H:%M:%S", &now);
271
272 static const char log_characters[] = "XXVDIWEF";
273 static_assert(arraysize(log_characters) - 1 == ANDROID_LOG_SILENT,
274 "Mismatch in size of log_characters and values in android_LogPriority");
275 int priority =
276 logger_data->priority > ANDROID_LOG_SILENT ? ANDROID_LOG_FATAL : logger_data->priority;
277 char priority_char = log_characters[priority];
278 uint64_t tid = GetThreadId();
279
280 if (logger_data->file != nullptr) {
281 fprintf(stderr, "%s %c %s %5d %5" PRIu64 " %s:%u] %s\n",
282 logger_data->tag ? logger_data->tag : "nullptr", priority_char, timestamp, getpid(),
283 tid, logger_data->file, logger_data->line, message);
284 } else {
285 fprintf(stderr, "%s %c %s %5d %5" PRIu64 " %s\n",
286 logger_data->tag ? logger_data->tag : "nullptr", priority_char, timestamp, getpid(),
287 tid, message);
288 }
289}
290
291void __android_log_logd_logger(const struct __android_logger_data* logger_data,
292 const char* message) {
293 int buffer_id = logger_data->buffer_id == LOG_ID_DEFAULT ? LOG_ID_MAIN : logger_data->buffer_id;
294
295 struct iovec vec[3];
296 vec[0].iov_base =
297 const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(&logger_data->priority));
298 vec[0].iov_len = 1;
299 vec[1].iov_base = const_cast<void*>(static_cast<const void*>(logger_data->tag));
300 vec[1].iov_len = strlen(logger_data->tag) + 1;
301 vec[2].iov_base = const_cast<void*>(static_cast<const void*>(message));
302 vec[2].iov_len = strlen(message) + 1;
303
304 write_to_log(static_cast<log_id_t>(buffer_id), vec, 3);
305}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800306
Tom Cherry2d9779e2019-02-08 11:46:19 -0800307int __android_log_write(int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800308 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800309}
310
Tom Cherry349b0c42020-01-08 14:47:42 -0800311void __android_log_write_logger_data(__android_logger_data* logger_data, const char* msg) {
Tom Cherryff464b12020-01-27 13:49:26 -0800312 ErrnoRestorer errno_restorer;
313
Tom Cherry69ee5dd2020-01-22 07:48:42 -0800314 auto tag_lock = std::shared_lock{default_tag_lock, std::defer_lock};
315 if (logger_data->tag == nullptr) {
316 tag_lock.lock();
317 logger_data->tag = GetDefaultTag().c_str();
318 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800319
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800320#if __BIONIC__
Tom Cherry349b0c42020-01-08 14:47:42 -0800321 if (logger_data->priority == ANDROID_LOG_FATAL) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800322 android_set_abort_message(msg);
323 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800324#endif
325
Tom Cherry349b0c42020-01-08 14:47:42 -0800326 auto lock = std::shared_lock{logger_function_lock};
327 logger_function(logger_data, msg);
328}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800329
Tom Cherry349b0c42020-01-08 14:47:42 -0800330int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
Tom Cherryff464b12020-01-27 13:49:26 -0800331 ErrnoRestorer errno_restorer;
332
Tom Cherry96e7ef52020-01-22 08:20:03 -0800333 if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
334 return 0;
335 }
336
Tom Cherry349b0c42020-01-08 14:47:42 -0800337 __android_logger_data logger_data = {sizeof(__android_logger_data), bufID, prio, tag, nullptr, 0};
338 __android_log_write_logger_data(&logger_data, msg);
339 return 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800340}
341
Tom Cherry2d9779e2019-02-08 11:46:19 -0800342int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
Tom Cherryff464b12020-01-27 13:49:26 -0800343 ErrnoRestorer errno_restorer;
344
Tom Cherry96e7ef52020-01-22 08:20:03 -0800345 if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
346 return 0;
347 }
348
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800349 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800350
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800351 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800352
Tom Cherry96e7ef52020-01-22 08:20:03 -0800353 __android_logger_data logger_data = {
354 sizeof(__android_logger_data), LOG_ID_MAIN, prio, tag, nullptr, 0};
355 __android_log_write_logger_data(&logger_data, buf);
356 return 1;
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, ...) {
Tom Cherryff464b12020-01-27 13:49:26 -0800360 ErrnoRestorer errno_restorer;
361
Tom Cherry96e7ef52020-01-22 08:20:03 -0800362 if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
363 return 0;
364 }
365
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800366 va_list ap;
367 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800368
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800369 va_start(ap, fmt);
370 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
371 va_end(ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800372
Tom Cherry96e7ef52020-01-22 08:20:03 -0800373 __android_logger_data logger_data = {
374 sizeof(__android_logger_data), LOG_ID_MAIN, prio, tag, nullptr, 0};
375 __android_log_write_logger_data(&logger_data, buf);
376 return 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800377}
378
Tom Cherry2d9779e2019-02-08 11:46:19 -0800379int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
Tom Cherryff464b12020-01-27 13:49:26 -0800380 ErrnoRestorer errno_restorer;
381
Tom Cherry96e7ef52020-01-22 08:20:03 -0800382 if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
383 return 0;
384 }
385
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800386 va_list ap;
387 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800388
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800389 va_start(ap, fmt);
390 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
391 va_end(ap);
392
Tom Cherry96e7ef52020-01-22 08:20:03 -0800393 __android_logger_data logger_data = {sizeof(__android_logger_data), bufID, prio, tag, nullptr, 0};
394 __android_log_write_logger_data(&logger_data, buf);
395 return 1;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800396}
397
Tom Cherry2d9779e2019-02-08 11:46:19 -0800398void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800399 char buf[LOG_BUF_SIZE];
400
401 if (fmt) {
402 va_list ap;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800403 va_start(ap, fmt);
404 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
405 va_end(ap);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800406 } else {
407 /* Msg not provided, log condition. N.B. Do not use cond directly as
408 * format string as it could contain spurious '%' syntax (e.g.
409 * "%d" in "blocks%devs == 0").
410 */
411 if (cond)
412 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
413 else
414 strcpy(buf, "Unspecified assertion failed");
415 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800416
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800417 // Log assertion failures to stderr for the benefit of "adb shell" users
418 // and gtests (http://b/23675822).
Tom Cherry6f6ef392019-01-16 14:17:08 -0800419 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
420 TEMP_FAILURE_RETRY(write(2, "\n", 1));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800421
422 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
Tom Cherry349b0c42020-01-08 14:47:42 -0800423 __android_log_call_aborter(buf);
424 abort();
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800425}
426
Tom Cherry2d9779e2019-02-08 11:46:19 -0800427int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
Tom Cherryff464b12020-01-27 13:49:26 -0800428 ErrnoRestorer errno_restorer;
429
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800430 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800431
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800432 vec[0].iov_base = &tag;
433 vec[0].iov_len = sizeof(tag);
434 vec[1].iov_base = (void*)payload;
435 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800436
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800437 return write_to_log(LOG_ID_EVENTS, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800438}
439
Tom Cherry2d9779e2019-02-08 11:46:19 -0800440int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
Tom Cherryff464b12020-01-27 13:49:26 -0800441 ErrnoRestorer errno_restorer;
442
Stefan Lafon701a0652017-08-24 20:14:06 -0700443 struct iovec vec[2];
444
445 vec[0].iov_base = &tag;
446 vec[0].iov_len = sizeof(tag);
447 vec[1].iov_base = (void*)payload;
448 vec[1].iov_len = len;
449
450 return write_to_log(LOG_ID_STATS, vec, 2);
451}
452
Tom Cherry2d9779e2019-02-08 11:46:19 -0800453int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
Tom Cherryff464b12020-01-27 13:49:26 -0800454 ErrnoRestorer errno_restorer;
455
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800456 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800457
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800458 vec[0].iov_base = &tag;
459 vec[0].iov_len = sizeof(tag);
460 vec[1].iov_base = (void*)payload;
461 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800462
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800463 return write_to_log(LOG_ID_SECURITY, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800464}
465
466/*
467 * Like __android_log_bwrite, but takes the type as well. Doesn't work
468 * for the general case where we're generating lists of stuff, but very
469 * handy if we just want to dump an integer into the log.
470 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800471int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
Tom Cherryff464b12020-01-27 13:49:26 -0800472 ErrnoRestorer errno_restorer;
473
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800474 struct iovec vec[3];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800475
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800476 vec[0].iov_base = &tag;
477 vec[0].iov_len = sizeof(tag);
478 vec[1].iov_base = &type;
479 vec[1].iov_len = sizeof(type);
480 vec[2].iov_base = (void*)payload;
481 vec[2].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800482
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800483 return write_to_log(LOG_ID_EVENTS, vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800484}
485
486/*
487 * Like __android_log_bwrite, but used for writing strings to the
488 * event log.
489 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800490int __android_log_bswrite(int32_t tag, const char* payload) {
Tom Cherryff464b12020-01-27 13:49:26 -0800491 ErrnoRestorer errno_restorer;
492
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800493 struct iovec vec[4];
494 char type = EVENT_TYPE_STRING;
495 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800496
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800497 vec[0].iov_base = &tag;
498 vec[0].iov_len = sizeof(tag);
499 vec[1].iov_base = &type;
500 vec[1].iov_len = sizeof(type);
501 vec[2].iov_base = &len;
502 vec[2].iov_len = sizeof(len);
503 vec[3].iov_base = (void*)payload;
504 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800505
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800506 return write_to_log(LOG_ID_EVENTS, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800507}
508
509/*
510 * Like __android_log_security_bwrite, but used for writing strings to the
511 * security log.
512 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800513int __android_log_security_bswrite(int32_t tag, const char* payload) {
Tom Cherryff464b12020-01-27 13:49:26 -0800514 ErrnoRestorer errno_restorer;
515
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800516 struct iovec vec[4];
517 char type = EVENT_TYPE_STRING;
518 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800519
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800520 vec[0].iov_base = &tag;
521 vec[0].iov_len = sizeof(tag);
522 vec[1].iov_base = &type;
523 vec[1].iov_len = sizeof(type);
524 vec[2].iov_base = &len;
525 vec[2].iov_len = sizeof(len);
526 vec[3].iov_base = (void*)payload;
527 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800528
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800529 return write_to_log(LOG_ID_SECURITY, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800530}