1 /*
2 * Copyright (C) 2017 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 <fcntl.h>
19 #include <pthread.h>
20 #if !defined(__MINGW32__)
21 #include <pwd.h>
22 #endif
23 #include <log/uio.h>
24 #include <sched.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/types.h>
28
29 #include <cutils/list.h> /* template, no library dependency */
30 #include <log/log_transport.h>
31 #include <private/android_filesystem_config.h>
32 #include <private/android_logger.h>
33 #include <system/thread_defs.h>
34
35 #include "config_read.h"
36 #include "config_write.h"
37 #include "log_portability.h"
38 #include "logger.h"
39
40 static const char baseServiceName[] = "android.logd";
41
42 static int writeToLocalInit();
43 static int writeToLocalAvailable(log_id_t logId);
44 static void writeToLocalReset();
45 static int writeToLocalWrite(log_id_t logId, struct timespec* ts,
46 struct iovec* vec, size_t nr);
47
48 LIBLOG_HIDDEN struct android_log_transport_write localLoggerWrite = {
49 .node = { &localLoggerWrite.node, &localLoggerWrite.node },
50 .context.priv = NULL,
51 .name = "local",
52 .available = writeToLocalAvailable,
53 .open = writeToLocalInit,
54 .close = writeToLocalReset,
55 .write = writeToLocalWrite,
56 };
57
58 static int writeToLocalVersion(struct android_log_logger* logger,
59 struct android_log_transport_context* transp);
60 static int writeToLocalRead(struct android_log_logger_list* logger_list,
61 struct android_log_transport_context* transp,
62 struct log_msg* log_msg);
63 static int writeToLocalPoll(struct android_log_logger_list* logger_list,
64 struct android_log_transport_context* transp);
65 static void writeToLocalClose(struct android_log_logger_list* logger_list,
66 struct android_log_transport_context* transp);
67 static int writeToLocalClear(struct android_log_logger* logger,
68 struct android_log_transport_context* transp);
69 static ssize_t writeToLocalGetSize(struct android_log_logger* logger,
70 struct android_log_transport_context* transp);
71 static ssize_t writeToLocalSetSize(
72 struct android_log_logger* logger,
73 struct android_log_transport_context* transp __unused, size_t size);
74 static ssize_t writeToLocalGetReadbleSize(
75 struct android_log_logger* logger,
76 struct android_log_transport_context* transp);
77
78 struct android_log_transport_read localLoggerRead = {
79 .node = { &localLoggerRead.node, &localLoggerRead.node },
80 .name = "local",
81 .available = writeToLocalAvailable,
82 .version = writeToLocalVersion,
83 .read = writeToLocalRead,
84 .poll = writeToLocalPoll,
85 .close = writeToLocalClose,
86 .clear = writeToLocalClear,
87 .getSize = writeToLocalGetSize,
88 .setSize = writeToLocalSetSize,
89 .getReadableSize = writeToLocalGetReadbleSize,
90 .getPrune = NULL,
91 .setPrune = NULL,
92 .getStats = NULL,
93 };
94
95 struct LogBufferElement {
96 struct listnode node;
97 log_id_t logId;
98 pid_t tid;
99 log_time timestamp;
100 unsigned short len;
101 char msg[];
102 };
103
104 static const size_t MAX_SIZE_DEFAULT = 32768;
105
106 /*
107 * Number of log buffers we support with the following assumption:
108 * . . .
109 * LOG_ID_SECURITY = 5, // security logs go to the system logs only
110 * LOG_ID_KERNEL = 6, // place last, third-parties can not use it
111 * LOG_ID_MAX
112 * } log_id_t;
113 *
114 * Confirm the following should <log/log_id.h> be adjusted in the future.
115 */
116 #define NUMBER_OF_LOG_BUFFERS \
117 ((LOG_ID_SECURITY == (LOG_ID_MAX - 2)) ? LOG_ID_SECURITY : LOG_ID_KERNEL)
118 #define BLOCK_LOG_BUFFERS(id) \
119 (((id) == LOG_ID_SECURITY) || ((id) == LOG_ID_KERNEL))
120
121 static struct LogBuffer {
122 struct listnode head;
123 pthread_rwlock_t listLock;
124 char* serviceName; /* Also indicates ready by having a value */
125 /* Order and proximity important for memset */
126 size_t number[NUMBER_OF_LOG_BUFFERS]; /* clear memset */
127 size_t size[NUMBER_OF_LOG_BUFFERS]; /* clear memset */
128 size_t totalSize[NUMBER_OF_LOG_BUFFERS]; /* init memset */
129 size_t maxSize[NUMBER_OF_LOG_BUFFERS]; /* init MAX_SIZE_DEFAULT */
130 struct listnode* last[NUMBER_OF_LOG_BUFFERS]; /* init &head */
131 } logbuf = {
132 .head = { &logbuf.head, &logbuf.head }, .listLock = PTHREAD_RWLOCK_INITIALIZER,
133 };
134
LogBufferInit(struct LogBuffer * log)135 static void LogBufferInit(struct LogBuffer* log) {
136 size_t i;
137
138 pthread_rwlock_wrlock(&log->listLock);
139 list_init(&log->head);
140 memset(log->number, 0,
141 sizeof(log->number) + sizeof(log->size) + sizeof(log->totalSize));
142 for (i = 0; i < NUMBER_OF_LOG_BUFFERS; ++i) {
143 log->maxSize[i] = MAX_SIZE_DEFAULT;
144 log->last[i] = &log->head;
145 }
146 #ifdef __BIONIC__
147 asprintf(&log->serviceName, "%s@%d:%d", baseServiceName, __android_log_uid(),
148 getpid());
149 #else
150 char buffer[sizeof(baseServiceName) + 1 + 5 + 1 + 5 + 8];
151 snprintf(buffer, sizeof(buffer), "%s@%d:%d", baseServiceName,
152 __android_log_uid(), getpid());
153 log->serviceName = strdup(buffer);
154 #endif
155 pthread_rwlock_unlock(&log->listLock);
156 }
157
LogBufferClear(struct LogBuffer * log)158 static void LogBufferClear(struct LogBuffer* log) {
159 size_t i;
160 struct listnode* node;
161
162 pthread_rwlock_wrlock(&log->listLock);
163 memset(log->number, 0, sizeof(log->number) + sizeof(log->size));
164 for (i = 0; i < NUMBER_OF_LOG_BUFFERS; ++i) {
165 log->last[i] = &log->head;
166 }
167 while ((node = list_head(&log->head)) != &log->head) {
168 struct LogBufferElement* element;
169
170 element = node_to_item(node, struct LogBufferElement, node);
171 list_remove(node);
172 free(element);
173 }
174 pthread_rwlock_unlock(&log->listLock);
175 }
176
LogBufferFree(struct LogBuffer * log)177 static inline void LogBufferFree(struct LogBuffer* log) {
178 pthread_rwlock_wrlock(&log->listLock);
179 free(log->serviceName);
180 log->serviceName = NULL;
181 pthread_rwlock_unlock(&log->listLock);
182 LogBufferClear(log);
183 }
184
LogBufferLog(struct LogBuffer * log,struct LogBufferElement * element)185 static int LogBufferLog(struct LogBuffer* log,
186 struct LogBufferElement* element) {
187 log_id_t logId = element->logId;
188
189 pthread_rwlock_wrlock(&log->listLock);
190 log->number[logId]++;
191 log->size[logId] += element->len;
192 log->totalSize[logId] += element->len;
193 /* prune entry(s) until enough space is available */
194 if (log->last[logId] == &log->head) {
195 log->last[logId] = list_tail(&log->head);
196 }
197 while (log->size[logId] > log->maxSize[logId]) {
198 struct listnode* node = log->last[logId];
199 struct LogBufferElement* e;
200 struct android_log_logger_list* logger_list;
201
202 e = node_to_item(node, struct LogBufferElement, node);
203 log->number[logId]--;
204 log->size[logId] -= e->len;
205 logger_list_rdlock();
206 logger_list_for_each(logger_list) {
207 struct android_log_transport_context* transp;
208
209 transport_context_for_each(transp, logger_list) {
210 if ((transp->transport == &localLoggerRead) &&
211 (transp->context.node == node)) {
212 if (node == &log->head) {
213 transp->context.node = &log->head;
214 } else {
215 transp->context.node = node->next;
216 }
217 }
218 }
219 }
220 logger_list_unlock();
221 if (node != &log->head) {
222 log->last[logId] = node->prev;
223 }
224 list_remove(node);
225 free(e);
226 }
227 /* add entry to list */
228 list_add_head(&log->head, &element->node);
229 /* ToDo: wake up all readers */
230 pthread_rwlock_unlock(&log->listLock);
231
232 return element->len;
233 }
234
235 /*
236 * return zero if permitted to log directly to logd,
237 * return 1 if binder server started and
238 * return negative error number if failed to start binder server.
239 */
writeToLocalInit()240 static int writeToLocalInit() {
241 pthread_attr_t attr;
242 struct LogBuffer* log;
243
244 if (writeToLocalAvailable(LOG_ID_MAIN) < 0) {
245 return -EPERM;
246 }
247
248 log = &logbuf;
249 if (!log->serviceName) {
250 LogBufferInit(log);
251 }
252
253 if (!log->serviceName) {
254 LogBufferFree(log);
255 return -ENOMEM;
256 }
257
258 return EPERM; /* successful local-only logging */
259 }
260
writeToLocalReset()261 static void writeToLocalReset() {
262 LogBufferFree(&logbuf);
263 }
264
writeToLocalAvailable(log_id_t logId)265 static int writeToLocalAvailable(log_id_t logId) {
266 #if !defined(__MINGW32__)
267 uid_t uid;
268 #endif
269
270 if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
271 return -EINVAL;
272 }
273
274 /* Android hard coded permitted, system goes to logd */
275 #if !defined(__MINGW32__)
276 if (__android_log_transport == LOGGER_DEFAULT) {
277 uid = __android_log_uid();
278 if ((uid < AID_APP) && (getpwuid(uid) != NULL)) {
279 return -EPERM;
280 }
281 }
282 #endif
283
284 /* ToDo: Ask package manager for LOGD permissions */
285 /* Assume we do _not_ have permissions to go to LOGD, so must go local */
286 return 0;
287 }
288
writeToLocalWrite(log_id_t logId,struct timespec * ts,struct iovec * vec,size_t nr)289 static int writeToLocalWrite(log_id_t logId, struct timespec* ts,
290 struct iovec* vec, size_t nr) {
291 size_t len, i;
292 struct LogBufferElement* element;
293
294 if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
295 return -EINVAL;
296 }
297
298 len = 0;
299 for (i = 0; i < nr; ++i) {
300 len += vec[i].iov_len;
301 }
302
303 if (len > LOGGER_ENTRY_MAX_PAYLOAD) {
304 len = LOGGER_ENTRY_MAX_PAYLOAD;
305 }
306 element = (struct LogBufferElement*)calloc(
307 1, sizeof(struct LogBufferElement) + len + 1);
308 if (!element) {
309 return errno ? -errno : -ENOMEM;
310 }
311 element->timestamp.tv_sec = ts->tv_sec;
312 element->timestamp.tv_nsec = ts->tv_nsec;
313 #ifdef __BIONIC__
314 element->tid = gettid();
315 #else
316 element->tid = getpid();
317 #endif
318 element->logId = logId;
319 element->len = len;
320
321 char* cp = element->msg;
322 for (i = 0; i < nr; ++i) {
323 size_t iov_len = vec[i].iov_len;
324 if (iov_len > len) {
325 iov_len = len;
326 }
327 memcpy(cp, vec[i].iov_base, iov_len);
328 len -= iov_len;
329 if (len == 0) {
330 break;
331 }
332 cp += iov_len;
333 }
334
335 return LogBufferLog(&logbuf, element);
336 }
337
writeToLocalVersion(struct android_log_logger * logger __unused,struct android_log_transport_context * transp __unused)338 static int writeToLocalVersion(struct android_log_logger* logger __unused,
339 struct android_log_transport_context* transp
340 __unused) {
341 return 3;
342 }
343
344 /* within reader lock, serviceName already validated */
writeToLocalNode(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp)345 static struct listnode* writeToLocalNode(
346 struct android_log_logger_list* logger_list,
347 struct android_log_transport_context* transp) {
348 struct listnode* node;
349 unsigned logMask;
350 unsigned int tail;
351
352 node = transp->context.node;
353 if (node) {
354 return node;
355 }
356
357 if (!logger_list->tail) {
358 return transp->context.node = &logbuf.head;
359 }
360
361 logMask = transp->logMask;
362 tail = logger_list->tail;
363
364 for (node = list_head(&logbuf.head); node != &logbuf.head; node = node->next) {
365 struct LogBufferElement* element;
366 log_id_t logId;
367
368 element = node_to_item(node, struct LogBufferElement, node);
369 logId = element->logId;
370
371 if ((logMask & (1 << logId)) && !--tail) {
372 node = node->next;
373 break;
374 }
375 }
376 return transp->context.node = node;
377 }
378
writeToLocalRead(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp,struct log_msg * log_msg)379 static int writeToLocalRead(struct android_log_logger_list* logger_list,
380 struct android_log_transport_context* transp,
381 struct log_msg* log_msg) {
382 int ret;
383 struct listnode* node;
384 unsigned logMask;
385
386 pthread_rwlock_rdlock(&logbuf.listLock);
387 if (!logbuf.serviceName) {
388 pthread_rwlock_unlock(&logbuf.listLock);
389 return (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0;
390 }
391
392 logMask = transp->logMask;
393
394 node = writeToLocalNode(logger_list, transp);
395
396 ret = 0;
397
398 while (node != list_head(&logbuf.head)) {
399 struct LogBufferElement* element;
400 log_id_t logId;
401
402 node = node->prev;
403 element = node_to_item(node, struct LogBufferElement, node);
404 logId = element->logId;
405
406 if (logMask & (1 << logId)) {
407 ret = log_msg->entry_v3.len = element->len;
408 log_msg->entry_v3.hdr_size = sizeof(log_msg->entry_v3);
409 log_msg->entry_v3.pid = getpid();
410 log_msg->entry_v3.tid = element->tid;
411 log_msg->entry_v3.sec = element->timestamp.tv_sec;
412 log_msg->entry_v3.nsec = element->timestamp.tv_nsec;
413 log_msg->entry_v3.lid = logId;
414 memcpy(log_msg->entry_v3.msg, element->msg, ret);
415 ret += log_msg->entry_v3.hdr_size;
416 break;
417 }
418 }
419
420 transp->context.node = node;
421
422 /* ToDo: if blocking, and no entry, put reader to sleep */
423 pthread_rwlock_unlock(&logbuf.listLock);
424 return ret;
425 }
426
writeToLocalPoll(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp)427 static int writeToLocalPoll(struct android_log_logger_list* logger_list,
428 struct android_log_transport_context* transp) {
429 int ret = (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0;
430
431 pthread_rwlock_rdlock(&logbuf.listLock);
432
433 if (logbuf.serviceName) {
434 unsigned logMask = transp->logMask;
435 struct listnode* node = writeToLocalNode(logger_list, transp);
436
437 ret = (node != list_head(&logbuf.head));
438 if (ret) {
439 do {
440 ret = !!(logMask &
441 (1 << (node_to_item(node->prev, struct LogBufferElement, node))
442 ->logId));
443 } while (!ret && ((node = node->prev) != list_head(&logbuf.head)));
444 }
445
446 transp->context.node = node;
447 }
448
449 pthread_rwlock_unlock(&logbuf.listLock);
450
451 return ret;
452 }
453
writeToLocalClose(struct android_log_logger_list * logger_list __unused,struct android_log_transport_context * transp)454 static void writeToLocalClose(struct android_log_logger_list* logger_list
455 __unused,
456 struct android_log_transport_context* transp) {
457 pthread_rwlock_wrlock(&logbuf.listLock);
458 transp->context.node = list_head(&logbuf.head);
459 pthread_rwlock_unlock(&logbuf.listLock);
460 }
461
writeToLocalClear(struct android_log_logger * logger,struct android_log_transport_context * unused __unused)462 static int writeToLocalClear(struct android_log_logger* logger,
463 struct android_log_transport_context* unused
464 __unused) {
465 log_id_t logId = logger->logId;
466 struct listnode *node, *n;
467
468 if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
469 return -EINVAL;
470 }
471
472 pthread_rwlock_wrlock(&logbuf.listLock);
473 logbuf.number[logId] = 0;
474 logbuf.last[logId] = &logbuf.head;
475 list_for_each_safe(node, n, &logbuf.head) {
476 struct LogBufferElement* element;
477 element = node_to_item(node, struct LogBufferElement, node);
478
479 if (logId == element->logId) {
480 struct android_log_logger_list* logger_list;
481
482 logger_list_rdlock();
483 logger_list_for_each(logger_list) {
484 struct android_log_transport_context* transp;
485
486 transport_context_for_each(transp, logger_list) {
487 if ((transp->transport == &localLoggerRead) &&
488 (transp->context.node == node)) {
489 transp->context.node = node->next;
490 }
491 }
492 }
493 logger_list_unlock();
494 list_remove(node);
495 free(element);
496 }
497 }
498
499 pthread_rwlock_unlock(&logbuf.listLock);
500
501 return 0;
502 }
503
writeToLocalGetSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)504 static ssize_t writeToLocalGetSize(struct android_log_logger* logger,
505 struct android_log_transport_context* transp
506 __unused) {
507 ssize_t ret = -EINVAL;
508 log_id_t logId = logger->logId;
509
510 if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) {
511 pthread_rwlock_rdlock(&logbuf.listLock);
512 ret = logbuf.maxSize[logId];
513 pthread_rwlock_unlock(&logbuf.listLock);
514 }
515
516 return ret;
517 }
518
writeToLocalSetSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused,size_t size)519 static ssize_t writeToLocalSetSize(
520 struct android_log_logger* logger,
521 struct android_log_transport_context* transp __unused, size_t size) {
522 ssize_t ret = -EINVAL;
523
524 if ((size > LOGGER_ENTRY_MAX_LEN) || (size < (4 * 1024 * 1024))) {
525 log_id_t logId = logger->logId;
526 if ((logId < NUMBER_OF_LOG_BUFFERS) || !BLOCK_LOG_BUFFERS(logId)) {
527 pthread_rwlock_wrlock(&logbuf.listLock);
528 ret = logbuf.maxSize[logId] = size;
529 pthread_rwlock_unlock(&logbuf.listLock);
530 }
531 }
532
533 return ret;
534 }
535
writeToLocalGetReadbleSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)536 static ssize_t writeToLocalGetReadbleSize(
537 struct android_log_logger* logger,
538 struct android_log_transport_context* transp __unused) {
539 ssize_t ret = -EINVAL;
540 log_id_t logId = logger->logId;
541
542 if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) {
543 pthread_rwlock_rdlock(&logbuf.listLock);
544 ret = logbuf.serviceName ? (ssize_t)logbuf.size[logId] : -EBADF;
545 pthread_rwlock_unlock(&logbuf.listLock);
546 }
547
548 return ret;
549 }
550