blob: d38b402ff483916065bd5c24dc092431c1f0665a [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
Dan Willemsen0910d2d2016-11-29 13:39:55 -080049#if defined(__ANDROID__)
Tom Cherry06e0fce2019-12-11 14:26:37 -080050static int check_log_uid_permissions() {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080051 uid_t uid = __android_log_uid();
Mark Salyzync33103c2016-03-28 16:20:29 -070052
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080053 /* Matches clientHasLogCredentials() in logd */
54 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
55 uid = geteuid();
Mark Salyzync33103c2016-03-28 16:20:29 -070056 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080057 gid_t gid = getgid();
58 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
59 gid = getegid();
60 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
61 int num_groups;
62 gid_t* groups;
Mark Salyzync33103c2016-03-28 16:20:29 -070063
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080064 num_groups = getgroups(0, NULL);
65 if (num_groups <= 0) {
66 return -EPERM;
67 }
Tom Cherry71ba1642019-01-10 10:37:36 -080068 groups = static_cast<gid_t*>(calloc(num_groups, sizeof(gid_t)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080069 if (!groups) {
70 return -ENOMEM;
71 }
72 num_groups = getgroups(num_groups, groups);
73 while (num_groups > 0) {
74 if (groups[num_groups - 1] == AID_LOG) {
75 break;
Mark Salyzync33103c2016-03-28 16:20:29 -070076 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080077 --num_groups;
78 }
79 free(groups);
80 if (num_groups <= 0) {
81 return -EPERM;
82 }
Mark Salyzync33103c2016-03-28 16:20:29 -070083 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080084 }
Mark Salyzync33103c2016-03-28 16:20:29 -070085 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080086 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080087 return 0;
Mark Salyzync33103c2016-03-28 16:20:29 -070088}
Tom Cherry06e0fce2019-12-11 14:26:37 -080089#endif
Mark Salyzync33103c2016-03-28 16:20:29 -070090
Mark Salyzyndf7a4c62016-08-23 10:23:36 -070091/*
92 * Release any logger resources. A new log write will immediately re-acquire.
93 */
Tom Cherry2d9779e2019-02-08 11:46:19 -080094void __android_log_close() {
Tom Cherry2beabe52019-10-01 13:05:58 -070095 if (android_log_write != nullptr) {
96 android_log_write->close();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080097 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -070098
Tom Cherry2beabe52019-10-01 13:05:58 -070099 if (android_log_persist_write != nullptr) {
100 android_log_persist_write->close();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800101 }
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700102
Mark Salyzyndf7a4c62016-08-23 10:23:36 -0700103}
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800104
Tom Cherry06e0fce2019-12-11 14:26:37 -0800105static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800106 int ret, save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800107 struct timespec ts;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800108
Mark Salyzyn72d37242018-03-07 10:42:06 -0800109 save_errno = errno;
Tom Cherry06e0fce2019-12-11 14:26:37 -0800110
111 if (log_id == LOG_ID_KERNEL) {
112 return -EINVAL;
113 }
114
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800115#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800116 clock_gettime(android_log_clockid(), &ts);
Mark Salyzyn142b43d2016-12-28 10:30:57 -0800117
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800118 if (log_id == LOG_ID_SECURITY) {
119 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800120 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800121 return -EINVAL;
122 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800123
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800124 ret = check_log_uid_permissions();
125 if (ret < 0) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800126 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800127 return ret;
128 }
129 if (!__android_log_security()) {
130 /* If only we could reset downstream logd counter */
Mark Salyzyn72d37242018-03-07 10:42:06 -0800131 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800132 return -EPERM;
133 }
Yao Chen025f05a2017-12-01 15:48:19 -0800134 } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800135 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800136 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800137 return -EINVAL;
138 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800139 } else {
Tom Cherry2187a412019-10-01 17:13:43 -0700140 int prio = *static_cast<int*>(vec[0].iov_base);
141 const char* tag = static_cast<const char*>(vec[1].iov_base);
142 size_t len = vec[1].iov_len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800143
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800144 if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800145 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800146 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800147 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800148 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800149#else
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800150 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
151 {
152 struct timeval tv;
153 gettimeofday(&tv, NULL);
154 ts.tv_sec = tv.tv_sec;
155 ts.tv_nsec = tv.tv_usec * 1000;
156 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800157#endif
158
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800159 ret = 0;
Tom Cherry2beabe52019-10-01 13:05:58 -0700160
Tom Cherry06e0fce2019-12-11 14:26:37 -0800161 if (android_log_write != nullptr) {
Tom Cherry2beabe52019-10-01 13:05:58 -0700162 ssize_t retval;
163 retval = android_log_write->write(log_id, &ts, vec, nr);
164 if (ret >= 0) {
165 ret = retval;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800166 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800167 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800168
Tom Cherry06e0fce2019-12-11 14:26:37 -0800169 if (android_log_persist_write != nullptr) {
Tom Cherry2beabe52019-10-01 13:05:58 -0700170 android_log_persist_write->write(log_id, &ts, vec, nr);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800171 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800172
Mark Salyzyn72d37242018-03-07 10:42:06 -0800173 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800174 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800175}
176
Tom Cherry2d9779e2019-02-08 11:46:19 -0800177int __android_log_write(int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800178 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800179}
180
Tom Cherry2d9779e2019-02-08 11:46:19 -0800181int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800182 if (!tag) tag = "";
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800183
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800184#if __BIONIC__
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800185 if (prio == ANDROID_LOG_FATAL) {
186 android_set_abort_message(msg);
187 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800188#endif
189
Elliott Hughesde3ad1d2015-04-03 13:24:37 -0700190 struct iovec vec[3];
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800191 vec[0].iov_base = (unsigned char*)&prio;
192 vec[0].iov_len = 1;
193 vec[1].iov_base = (void*)tag;
194 vec[1].iov_len = strlen(tag) + 1;
195 vec[2].iov_base = (void*)msg;
196 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800197
Tom Cherry71ba1642019-01-10 10:37:36 -0800198 return write_to_log(static_cast<log_id_t>(bufID), vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800199}
200
Tom Cherry2d9779e2019-02-08 11:46:19 -0800201int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800202 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800203
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800204 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800205
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800206 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800207}
208
Tom Cherry2d9779e2019-02-08 11:46:19 -0800209int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800210 va_list ap;
211 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800212
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800213 va_start(ap, fmt);
214 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
215 va_end(ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800216
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800217 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800218}
219
Tom Cherry2d9779e2019-02-08 11:46:19 -0800220int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800221 va_list ap;
222 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800223
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800224 va_start(ap, fmt);
225 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
226 va_end(ap);
227
228 return __android_log_buf_write(bufID, prio, tag, buf);
229}
230
Tom Cherry2d9779e2019-02-08 11:46:19 -0800231void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800232 char buf[LOG_BUF_SIZE];
233
234 if (fmt) {
235 va_list ap;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800236 va_start(ap, fmt);
237 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
238 va_end(ap);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800239 } else {
240 /* Msg not provided, log condition. N.B. Do not use cond directly as
241 * format string as it could contain spurious '%' syntax (e.g.
242 * "%d" in "blocks%devs == 0").
243 */
244 if (cond)
245 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
246 else
247 strcpy(buf, "Unspecified assertion failed");
248 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800249
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800250 // Log assertion failures to stderr for the benefit of "adb shell" users
251 // and gtests (http://b/23675822).
Tom Cherry6f6ef392019-01-16 14:17:08 -0800252 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
253 TEMP_FAILURE_RETRY(write(2, "\n", 1));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800254
255 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
256 abort(); /* abort so we have a chance to debug the situation */
257 /* NOTREACHED */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800258}
259
Tom Cherry2d9779e2019-02-08 11:46:19 -0800260int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800261 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800262
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800263 vec[0].iov_base = &tag;
264 vec[0].iov_len = sizeof(tag);
265 vec[1].iov_base = (void*)payload;
266 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800267
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800268 return write_to_log(LOG_ID_EVENTS, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800269}
270
Tom Cherry2d9779e2019-02-08 11:46:19 -0800271int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
Stefan Lafon701a0652017-08-24 20:14:06 -0700272 struct iovec vec[2];
273
274 vec[0].iov_base = &tag;
275 vec[0].iov_len = sizeof(tag);
276 vec[1].iov_base = (void*)payload;
277 vec[1].iov_len = len;
278
279 return write_to_log(LOG_ID_STATS, vec, 2);
280}
281
Tom Cherry2d9779e2019-02-08 11:46:19 -0800282int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800283 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800284
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800285 vec[0].iov_base = &tag;
286 vec[0].iov_len = sizeof(tag);
287 vec[1].iov_base = (void*)payload;
288 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800289
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800290 return write_to_log(LOG_ID_SECURITY, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800291}
292
293/*
294 * Like __android_log_bwrite, but takes the type as well. Doesn't work
295 * for the general case where we're generating lists of stuff, but very
296 * handy if we just want to dump an integer into the log.
297 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800298int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800299 struct iovec vec[3];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800300
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800301 vec[0].iov_base = &tag;
302 vec[0].iov_len = sizeof(tag);
303 vec[1].iov_base = &type;
304 vec[1].iov_len = sizeof(type);
305 vec[2].iov_base = (void*)payload;
306 vec[2].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800307
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800308 return write_to_log(LOG_ID_EVENTS, vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800309}
310
311/*
312 * Like __android_log_bwrite, but used for writing strings to the
313 * event log.
314 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800315int __android_log_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800316 struct iovec vec[4];
317 char type = EVENT_TYPE_STRING;
318 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800319
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800320 vec[0].iov_base = &tag;
321 vec[0].iov_len = sizeof(tag);
322 vec[1].iov_base = &type;
323 vec[1].iov_len = sizeof(type);
324 vec[2].iov_base = &len;
325 vec[2].iov_len = sizeof(len);
326 vec[3].iov_base = (void*)payload;
327 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800328
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800329 return write_to_log(LOG_ID_EVENTS, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800330}
331
332/*
333 * Like __android_log_security_bwrite, but used for writing strings to the
334 * security log.
335 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800336int __android_log_security_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800337 struct iovec vec[4];
338 char type = EVENT_TYPE_STRING;
339 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800340
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800341 vec[0].iov_base = &tag;
342 vec[0].iov_len = sizeof(tag);
343 vec[1].iov_base = &type;
344 vec[1].iov_len = sizeof(type);
345 vec[2].iov_base = &len;
346 vec[2].iov_len = sizeof(len);
347 vec[3].iov_base = (void*)payload;
348 vec[3].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_SECURITY, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800351}