blob: f55f4354c69359e21367b24b98209f0b04231f68 [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
Tom Cherry97ec4ee2019-10-02 10:52:55 -070034#if (FAKE_LOG_DEVICE == 0)
Tom Cherry21bb36c2020-01-08 15:18:26 -080035#include "logd_writer.h"
36#include "pmsg_writer.h"
Tom Cherry97ec4ee2019-10-02 10:52:55 -070037#else
Tom Cherry21bb36c2020-01-08 15:18:26 -080038#include "fake_log_device.h"
Tom Cherry97ec4ee2019-10-02 10:52:55 -070039#endif
Tom Cherry2beabe52019-10-01 13:05:58 -070040
Tom Cherry21bb36c2020-01-08 15:18:26 -080041#define LOG_BUF_SIZE 1024
42
Dan Willemsen0910d2d2016-11-29 13:39:55 -080043#if defined(__ANDROID__)
Tom Cherry06e0fce2019-12-11 14:26:37 -080044static int check_log_uid_permissions() {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080045 uid_t uid = __android_log_uid();
Mark Salyzync33103c2016-03-28 16:20:29 -070046
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080047 /* Matches clientHasLogCredentials() in logd */
48 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
49 uid = geteuid();
Mark Salyzync33103c2016-03-28 16:20:29 -070050 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080051 gid_t gid = getgid();
52 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
53 gid = getegid();
54 if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
55 int num_groups;
56 gid_t* groups;
Mark Salyzync33103c2016-03-28 16:20:29 -070057
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080058 num_groups = getgroups(0, NULL);
59 if (num_groups <= 0) {
60 return -EPERM;
61 }
Tom Cherry71ba1642019-01-10 10:37:36 -080062 groups = static_cast<gid_t*>(calloc(num_groups, sizeof(gid_t)));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080063 if (!groups) {
64 return -ENOMEM;
65 }
66 num_groups = getgroups(num_groups, groups);
67 while (num_groups > 0) {
68 if (groups[num_groups - 1] == AID_LOG) {
69 break;
Mark Salyzync33103c2016-03-28 16:20:29 -070070 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080071 --num_groups;
72 }
73 free(groups);
74 if (num_groups <= 0) {
75 return -EPERM;
76 }
Mark Salyzync33103c2016-03-28 16:20:29 -070077 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080078 }
Mark Salyzync33103c2016-03-28 16:20:29 -070079 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080080 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080081 return 0;
Mark Salyzync33103c2016-03-28 16:20:29 -070082}
Tom Cherry06e0fce2019-12-11 14:26:37 -080083#endif
Mark Salyzync33103c2016-03-28 16:20:29 -070084
Mark Salyzyndf7a4c62016-08-23 10:23:36 -070085/*
86 * Release any logger resources. A new log write will immediately re-acquire.
87 */
Tom Cherry2d9779e2019-02-08 11:46:19 -080088void __android_log_close() {
Tom Cherry21bb36c2020-01-08 15:18:26 -080089#if (FAKE_LOG_DEVICE == 0)
90 LogdClose();
91 PmsgClose();
92#else
93 FakeClose();
94#endif
Mark Salyzyndf7a4c62016-08-23 10:23:36 -070095}
Mark Salyzyn018a96d2016-03-01 13:45:42 -080096
Tom Cherry06e0fce2019-12-11 14:26:37 -080097static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr) {
Mark Salyzyn72d37242018-03-07 10:42:06 -080098 int ret, save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080099 struct timespec ts;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800100
Mark Salyzyn72d37242018-03-07 10:42:06 -0800101 save_errno = errno;
Tom Cherry06e0fce2019-12-11 14:26:37 -0800102
103 if (log_id == LOG_ID_KERNEL) {
104 return -EINVAL;
105 }
106
Dan Willemsen0910d2d2016-11-29 13:39:55 -0800107#if defined(__ANDROID__)
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800108 clock_gettime(android_log_clockid(), &ts);
Mark Salyzyn142b43d2016-12-28 10:30:57 -0800109
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800110 if (log_id == LOG_ID_SECURITY) {
111 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800112 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800113 return -EINVAL;
114 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800115
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800116 ret = check_log_uid_permissions();
117 if (ret < 0) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800118 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800119 return ret;
120 }
121 if (!__android_log_security()) {
122 /* If only we could reset downstream logd counter */
Mark Salyzyn72d37242018-03-07 10:42:06 -0800123 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800124 return -EPERM;
125 }
Yao Chen025f05a2017-12-01 15:48:19 -0800126 } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800127 if (vec[0].iov_len < 4) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800128 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800129 return -EINVAL;
130 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800131 } else {
Tom Cherry2187a412019-10-01 17:13:43 -0700132 int prio = *static_cast<int*>(vec[0].iov_base);
133 const char* tag = static_cast<const char*>(vec[1].iov_base);
134 size_t len = vec[1].iov_len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800135
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800136 if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) {
Mark Salyzyn72d37242018-03-07 10:42:06 -0800137 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800138 return -EPERM;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800139 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800140 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800141#else
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800142 /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
143 {
144 struct timeval tv;
145 gettimeofday(&tv, NULL);
146 ts.tv_sec = tv.tv_sec;
147 ts.tv_nsec = tv.tv_usec * 1000;
148 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800149#endif
150
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800151 ret = 0;
Tom Cherry2beabe52019-10-01 13:05:58 -0700152
Tom Cherry21bb36c2020-01-08 15:18:26 -0800153#if (FAKE_LOG_DEVICE == 0)
154 ret = LogdWrite(log_id, &ts, vec, nr);
155 PmsgWrite(log_id, &ts, vec, nr);
156#else
157 ret = FakeWrite(log_id, &ts, vec, nr);
158#endif
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800159
Mark Salyzyn72d37242018-03-07 10:42:06 -0800160 errno = save_errno;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800161 return ret;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800162}
163
Tom Cherry2d9779e2019-02-08 11:46:19 -0800164int __android_log_write(int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800165 return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800166}
167
Tom Cherry2d9779e2019-02-08 11:46:19 -0800168int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800169 if (!tag) tag = "";
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800170
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800171#if __BIONIC__
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800172 if (prio == ANDROID_LOG_FATAL) {
173 android_set_abort_message(msg);
174 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800175#endif
176
Elliott Hughesde3ad1d2015-04-03 13:24:37 -0700177 struct iovec vec[3];
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800178 vec[0].iov_base = (unsigned char*)&prio;
179 vec[0].iov_len = 1;
180 vec[1].iov_base = (void*)tag;
181 vec[1].iov_len = strlen(tag) + 1;
182 vec[2].iov_base = (void*)msg;
183 vec[2].iov_len = strlen(msg) + 1;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800184
Tom Cherry71ba1642019-01-10 10:37:36 -0800185 return write_to_log(static_cast<log_id_t>(bufID), vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800186}
187
Tom Cherry2d9779e2019-02-08 11:46:19 -0800188int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800189 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800190
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800191 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800192
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800193 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800194}
195
Tom Cherry2d9779e2019-02-08 11:46:19 -0800196int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800197 va_list ap;
198 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800199
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800200 va_start(ap, fmt);
201 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
202 va_end(ap);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800203
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800204 return __android_log_write(prio, tag, buf);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800205}
206
Tom Cherry2d9779e2019-02-08 11:46:19 -0800207int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800208 va_list ap;
209 char buf[LOG_BUF_SIZE];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800210
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800211 va_start(ap, fmt);
212 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
213 va_end(ap);
214
215 return __android_log_buf_write(bufID, prio, tag, buf);
216}
217
Tom Cherry2d9779e2019-02-08 11:46:19 -0800218void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800219 char buf[LOG_BUF_SIZE];
220
221 if (fmt) {
222 va_list ap;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800223 va_start(ap, fmt);
224 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
225 va_end(ap);
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800226 } else {
227 /* Msg not provided, log condition. N.B. Do not use cond directly as
228 * format string as it could contain spurious '%' syntax (e.g.
229 * "%d" in "blocks%devs == 0").
230 */
231 if (cond)
232 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
233 else
234 strcpy(buf, "Unspecified assertion failed");
235 }
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800236
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800237 // Log assertion failures to stderr for the benefit of "adb shell" users
238 // and gtests (http://b/23675822).
Tom Cherry6f6ef392019-01-16 14:17:08 -0800239 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
240 TEMP_FAILURE_RETRY(write(2, "\n", 1));
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800241
242 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
243 abort(); /* abort so we have a chance to debug the situation */
244 /* NOTREACHED */
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800245}
246
Tom Cherry2d9779e2019-02-08 11:46:19 -0800247int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800248 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800249
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800250 vec[0].iov_base = &tag;
251 vec[0].iov_len = sizeof(tag);
252 vec[1].iov_base = (void*)payload;
253 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800254
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800255 return write_to_log(LOG_ID_EVENTS, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800256}
257
Tom Cherry2d9779e2019-02-08 11:46:19 -0800258int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
Stefan Lafon701a0652017-08-24 20:14:06 -0700259 struct iovec vec[2];
260
261 vec[0].iov_base = &tag;
262 vec[0].iov_len = sizeof(tag);
263 vec[1].iov_base = (void*)payload;
264 vec[1].iov_len = len;
265
266 return write_to_log(LOG_ID_STATS, vec, 2);
267}
268
Tom Cherry2d9779e2019-02-08 11:46:19 -0800269int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800270 struct iovec vec[2];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800271
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800272 vec[0].iov_base = &tag;
273 vec[0].iov_len = sizeof(tag);
274 vec[1].iov_base = (void*)payload;
275 vec[1].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800276
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800277 return write_to_log(LOG_ID_SECURITY, vec, 2);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800278}
279
280/*
281 * Like __android_log_bwrite, but takes the type as well. Doesn't work
282 * for the general case where we're generating lists of stuff, but very
283 * handy if we just want to dump an integer into the log.
284 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800285int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800286 struct iovec vec[3];
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800287
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800288 vec[0].iov_base = &tag;
289 vec[0].iov_len = sizeof(tag);
290 vec[1].iov_base = &type;
291 vec[1].iov_len = sizeof(type);
292 vec[2].iov_base = (void*)payload;
293 vec[2].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800294
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800295 return write_to_log(LOG_ID_EVENTS, vec, 3);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800296}
297
298/*
299 * Like __android_log_bwrite, but used for writing strings to the
300 * event log.
301 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800302int __android_log_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800303 struct iovec vec[4];
304 char type = EVENT_TYPE_STRING;
305 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800306
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800307 vec[0].iov_base = &tag;
308 vec[0].iov_len = sizeof(tag);
309 vec[1].iov_base = &type;
310 vec[1].iov_len = sizeof(type);
311 vec[2].iov_base = &len;
312 vec[2].iov_len = sizeof(len);
313 vec[3].iov_base = (void*)payload;
314 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800315
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800316 return write_to_log(LOG_ID_EVENTS, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800317}
318
319/*
320 * Like __android_log_security_bwrite, but used for writing strings to the
321 * security log.
322 */
Tom Cherry2d9779e2019-02-08 11:46:19 -0800323int __android_log_security_bswrite(int32_t tag, const char* payload) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800324 struct iovec vec[4];
325 char type = EVENT_TYPE_STRING;
326 uint32_t len = strlen(payload);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800327
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800328 vec[0].iov_base = &tag;
329 vec[0].iov_len = sizeof(tag);
330 vec[1].iov_base = &type;
331 vec[1].iov_len = sizeof(type);
332 vec[2].iov_base = &len;
333 vec[2].iov_len = sizeof(len);
334 vec[3].iov_base = (void*)payload;
335 vec[3].iov_len = len;
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800336
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800337 return write_to_log(LOG_ID_SECURITY, vec, 4);
Mark Salyzyn018a96d2016-03-01 13:45:42 -0800338}