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     LOG_ALWAYS_FATAL_IF(node == log->last[logId], "corrupted list");
226     free(e);
227   }
228   /* add entry to list */
229   list_add_head(&log->head, &element->node);
230   /* ToDo: wake up all readers */
231   pthread_rwlock_unlock(&log->listLock);
232 
233   return element->len;
234 }
235 
236 /*
237  * return zero if permitted to log directly to logd,
238  * return 1 if binder server started and
239  * return negative error number if failed to start binder server.
240  */
writeToLocalInit()241 static int writeToLocalInit() {
242   pthread_attr_t attr;
243   struct LogBuffer* log;
244 
245   if (writeToLocalAvailable(LOG_ID_MAIN) < 0) {
246     return -EPERM;
247   }
248 
249   log = &logbuf;
250   if (!log->serviceName) {
251     LogBufferInit(log);
252   }
253 
254   if (!log->serviceName) {
255     LogBufferFree(log);
256     return -ENOMEM;
257   }
258 
259   return EPERM; /* successful local-only logging */
260 }
261 
writeToLocalReset()262 static void writeToLocalReset() {
263   LogBufferFree(&logbuf);
264 }
265 
writeToLocalAvailable(log_id_t logId)266 static int writeToLocalAvailable(log_id_t logId) {
267 #if !defined(__MINGW32__)
268   uid_t uid;
269 #endif
270 
271   if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
272     return -EINVAL;
273   }
274 
275 /* Android hard coded permitted, system goes to logd */
276 #if !defined(__MINGW32__)
277   if (__android_log_transport == LOGGER_DEFAULT) {
278     uid = __android_log_uid();
279     if ((uid < AID_APP) && (getpwuid(uid) != NULL)) {
280       return -EPERM;
281     }
282   }
283 #endif
284 
285   /* ToDo: Ask package manager for LOGD permissions */
286   /* Assume we do _not_ have permissions to go to LOGD, so must go local */
287   return 0;
288 }
289 
writeToLocalWrite(log_id_t logId,struct timespec * ts,struct iovec * vec,size_t nr)290 static int writeToLocalWrite(log_id_t logId, struct timespec* ts,
291                              struct iovec* vec, size_t nr) {
292   size_t len, i;
293   struct LogBufferElement* element;
294 
295   if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
296     return -EINVAL;
297   }
298 
299   len = 0;
300   for (i = 0; i < nr; ++i) {
301     len += vec[i].iov_len;
302   }
303 
304   if (len > LOGGER_ENTRY_MAX_PAYLOAD) {
305     len = LOGGER_ENTRY_MAX_PAYLOAD;
306   }
307   element = (struct LogBufferElement*)calloc(
308       1, sizeof(struct LogBufferElement) + len + 1);
309   if (!element) {
310     return errno ? -errno : -ENOMEM;
311   }
312   element->timestamp.tv_sec = ts->tv_sec;
313   element->timestamp.tv_nsec = ts->tv_nsec;
314 #ifdef __BIONIC__
315   element->tid = gettid();
316 #else
317   element->tid = getpid();
318 #endif
319   element->logId = logId;
320   element->len = len;
321 
322   char* cp = element->msg;
323   for (i = 0; i < nr; ++i) {
324     size_t iov_len = vec[i].iov_len;
325     if (iov_len > len) {
326       iov_len = len;
327     }
328     memcpy(cp, vec[i].iov_base, iov_len);
329     len -= iov_len;
330     if (len == 0) {
331       break;
332     }
333     cp += iov_len;
334   }
335 
336   return LogBufferLog(&logbuf, element);
337 }
338 
writeToLocalVersion(struct android_log_logger * logger __unused,struct android_log_transport_context * transp __unused)339 static int writeToLocalVersion(struct android_log_logger* logger __unused,
340                                struct android_log_transport_context* transp
341                                    __unused) {
342   return 3;
343 }
344 
345 /* within reader lock, serviceName already validated */
writeToLocalNode(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp)346 static struct listnode* writeToLocalNode(
347     struct android_log_logger_list* logger_list,
348     struct android_log_transport_context* transp) {
349   struct listnode* node;
350   unsigned logMask;
351   unsigned int tail;
352 
353   node = transp->context.node;
354   if (node) {
355     return node;
356   }
357 
358   if (!logger_list->tail) {
359     return transp->context.node = &logbuf.head;
360   }
361 
362   logMask = transp->logMask;
363   tail = logger_list->tail;
364 
365   for (node = list_head(&logbuf.head); node != &logbuf.head; node = node->next) {
366     struct LogBufferElement* element;
367     log_id_t logId;
368 
369     element = node_to_item(node, struct LogBufferElement, node);
370     logId = element->logId;
371 
372     if ((logMask & (1 << logId)) && !--tail) {
373       node = node->next;
374       break;
375     }
376   }
377   return transp->context.node = node;
378 }
379 
writeToLocalRead(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp,struct log_msg * log_msg)380 static int writeToLocalRead(struct android_log_logger_list* logger_list,
381                             struct android_log_transport_context* transp,
382                             struct log_msg* log_msg) {
383   int ret;
384   struct listnode* node;
385   unsigned logMask;
386 
387   pthread_rwlock_rdlock(&logbuf.listLock);
388   if (!logbuf.serviceName) {
389     pthread_rwlock_unlock(&logbuf.listLock);
390     return (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0;
391   }
392 
393   logMask = transp->logMask;
394 
395   node = writeToLocalNode(logger_list, transp);
396 
397   ret = 0;
398 
399   while (node != list_head(&logbuf.head)) {
400     struct LogBufferElement* element;
401     log_id_t logId;
402 
403     node = node->prev;
404     element = node_to_item(node, struct LogBufferElement, node);
405     logId = element->logId;
406 
407     if (logMask & (1 << logId)) {
408       ret = log_msg->entry_v3.len = element->len;
409       log_msg->entry_v3.hdr_size = sizeof(log_msg->entry_v3);
410       log_msg->entry_v3.pid = getpid();
411       log_msg->entry_v3.tid = element->tid;
412       log_msg->entry_v3.sec = element->timestamp.tv_sec;
413       log_msg->entry_v3.nsec = element->timestamp.tv_nsec;
414       log_msg->entry_v3.lid = logId;
415       memcpy(log_msg->entry_v3.msg, element->msg, ret);
416       ret += log_msg->entry_v3.hdr_size;
417       break;
418     }
419   }
420 
421   transp->context.node = node;
422 
423   /* ToDo: if blocking, and no entry, put reader to sleep */
424   pthread_rwlock_unlock(&logbuf.listLock);
425   return ret;
426 }
427 
writeToLocalPoll(struct android_log_logger_list * logger_list,struct android_log_transport_context * transp)428 static int writeToLocalPoll(struct android_log_logger_list* logger_list,
429                             struct android_log_transport_context* transp) {
430   int ret = (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0;
431 
432   pthread_rwlock_rdlock(&logbuf.listLock);
433 
434   if (logbuf.serviceName) {
435     unsigned logMask = transp->logMask;
436     struct listnode* node = writeToLocalNode(logger_list, transp);
437 
438     ret = (node != list_head(&logbuf.head));
439     if (ret) {
440       do {
441         ret = !!(logMask &
442                  (1 << (node_to_item(node->prev, struct LogBufferElement, node))
443                            ->logId));
444       } while (!ret && ((node = node->prev) != list_head(&logbuf.head)));
445     }
446 
447     transp->context.node = node;
448   }
449 
450   pthread_rwlock_unlock(&logbuf.listLock);
451 
452   return ret;
453 }
454 
writeToLocalClose(struct android_log_logger_list * logger_list __unused,struct android_log_transport_context * transp)455 static void writeToLocalClose(struct android_log_logger_list* logger_list
456                                   __unused,
457                               struct android_log_transport_context* transp) {
458   pthread_rwlock_wrlock(&logbuf.listLock);
459   transp->context.node = list_head(&logbuf.head);
460   pthread_rwlock_unlock(&logbuf.listLock);
461 }
462 
writeToLocalClear(struct android_log_logger * logger,struct android_log_transport_context * unused __unused)463 static int writeToLocalClear(struct android_log_logger* logger,
464                              struct android_log_transport_context* unused
465                                  __unused) {
466   log_id_t logId = logger->logId;
467   struct listnode *node, *n;
468 
469   if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
470     return -EINVAL;
471   }
472 
473   pthread_rwlock_wrlock(&logbuf.listLock);
474   logbuf.number[logId] = 0;
475   logbuf.last[logId] = &logbuf.head;
476   list_for_each_safe(node, n, &logbuf.head) {
477     struct LogBufferElement* element;
478     element = node_to_item(node, struct LogBufferElement, node);
479 
480     if (logId == element->logId) {
481       struct android_log_logger_list* logger_list;
482 
483       logger_list_rdlock();
484       logger_list_for_each(logger_list) {
485         struct android_log_transport_context* transp;
486 
487         transport_context_for_each(transp, logger_list) {
488           if ((transp->transport == &localLoggerRead) &&
489               (transp->context.node == node)) {
490             transp->context.node = node->next;
491           }
492         }
493       }
494       logger_list_unlock();
495       list_remove(node);
496       free(element);
497     }
498   }
499 
500   pthread_rwlock_unlock(&logbuf.listLock);
501 
502   return 0;
503 }
504 
writeToLocalGetSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)505 static ssize_t writeToLocalGetSize(struct android_log_logger* logger,
506                                    struct android_log_transport_context* transp
507                                        __unused) {
508   ssize_t ret = -EINVAL;
509   log_id_t logId = logger->logId;
510 
511   if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) {
512     pthread_rwlock_rdlock(&logbuf.listLock);
513     ret = logbuf.maxSize[logId];
514     pthread_rwlock_unlock(&logbuf.listLock);
515   }
516 
517   return ret;
518 }
519 
writeToLocalSetSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused,size_t size)520 static ssize_t writeToLocalSetSize(
521     struct android_log_logger* logger,
522     struct android_log_transport_context* transp __unused, size_t size) {
523   ssize_t ret = -EINVAL;
524 
525   if ((size > LOGGER_ENTRY_MAX_LEN) || (size < (4 * 1024 * 1024))) {
526     log_id_t logId = logger->logId;
527     if ((logId < NUMBER_OF_LOG_BUFFERS) || !BLOCK_LOG_BUFFERS(logId)) {
528       pthread_rwlock_wrlock(&logbuf.listLock);
529       ret = logbuf.maxSize[logId] = size;
530       pthread_rwlock_unlock(&logbuf.listLock);
531     }
532   }
533 
534   return ret;
535 }
536 
writeToLocalGetReadbleSize(struct android_log_logger * logger,struct android_log_transport_context * transp __unused)537 static ssize_t writeToLocalGetReadbleSize(
538     struct android_log_logger* logger,
539     struct android_log_transport_context* transp __unused) {
540   ssize_t ret = -EINVAL;
541   log_id_t logId = logger->logId;
542 
543   if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) {
544     pthread_rwlock_rdlock(&logbuf.listLock);
545     ret = logbuf.serviceName ? (ssize_t)logbuf.size[logId] : -EBADF;
546     pthread_rwlock_unlock(&logbuf.listLock);
547   }
548 
549   return ret;
550 }
551