| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 1 | /* | 
 | 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 |  | 
 | 27 | #include <log/event_tag_map.h> | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 28 | #include <log/log_transport.h> | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 29 | #include <private/android_filesystem_config.h> | 
 | 30 | #include <private/android_logger.h> | 
 | 31 |  | 
| Mark Salyzyn | 7100288 | 2016-03-08 16:18:26 -0800 | [diff] [blame] | 32 | #include "config_read.h" /* __android_log_config_read_close() definition */ | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 33 | #include "config_write.h" | 
 | 34 | #include "log_portability.h" | 
 | 35 | #include "logger.h" | 
 | 36 |  | 
 | 37 | #define LOG_BUF_SIZE 1024 | 
 | 38 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 39 | static int __write_to_log_init(log_id_t, struct iovec* vec, size_t nr); | 
 | 40 | static int (*write_to_log)(log_id_t, struct iovec* vec, | 
 | 41 |                            size_t nr) = __write_to_log_init; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 42 |  | 
 | 43 | /* | 
 | 44 |  * This is used by the C++ code to decide if it should write logs through | 
 | 45 |  * the C code.  Basically, if /dev/socket/logd is available, we're running in | 
 | 46 |  * the simulator rather than a desktop tool and want to use the device. | 
 | 47 |  */ | 
 | 48 | static enum { | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 49 |   kLogUninitialized, | 
 | 50 |   kLogNotAvailable, | 
 | 51 |   kLogAvailable | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 52 | } g_log_status = kLogUninitialized; | 
 | 53 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 54 | static int check_log_uid_permissions() { | 
| Dan Willemsen | 0910d2d | 2016-11-29 13:39:55 -0800 | [diff] [blame] | 55 | #if defined(__ANDROID__) | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 56 |   uid_t uid = __android_log_uid(); | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 57 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 58 |   /* Matches clientHasLogCredentials() in logd */ | 
 | 59 |   if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) { | 
 | 60 |     uid = geteuid(); | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 61 |     if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) { | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 62 |       gid_t gid = getgid(); | 
 | 63 |       if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) { | 
 | 64 |         gid = getegid(); | 
 | 65 |         if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) { | 
 | 66 |           int num_groups; | 
 | 67 |           gid_t* groups; | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 68 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 69 |           num_groups = getgroups(0, NULL); | 
 | 70 |           if (num_groups <= 0) { | 
 | 71 |             return -EPERM; | 
 | 72 |           } | 
 | 73 |           groups = calloc(num_groups, sizeof(gid_t)); | 
 | 74 |           if (!groups) { | 
 | 75 |             return -ENOMEM; | 
 | 76 |           } | 
 | 77 |           num_groups = getgroups(num_groups, groups); | 
 | 78 |           while (num_groups > 0) { | 
 | 79 |             if (groups[num_groups - 1] == AID_LOG) { | 
 | 80 |               break; | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 81 |             } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 82 |             --num_groups; | 
 | 83 |           } | 
 | 84 |           free(groups); | 
 | 85 |           if (num_groups <= 0) { | 
 | 86 |             return -EPERM; | 
 | 87 |           } | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 88 |         } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 89 |       } | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 90 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 91 |   } | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 92 | #endif | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 93 |   return 0; | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 94 | } | 
 | 95 |  | 
 | 96 | static void __android_log_cache_available( | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 97 |     struct android_log_transport_write* node) { | 
 | 98 |   size_t i; | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 99 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 100 |   if (node->logMask) { | 
 | 101 |     return; | 
 | 102 |   } | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 103 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 104 |   for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) { | 
 | 105 |     if (node->write && (i != LOG_ID_KERNEL) && | 
 | 106 |         ((i != LOG_ID_SECURITY) || (check_log_uid_permissions() == 0)) && | 
 | 107 |         (!node->available || ((*node->available)(i) >= 0))) { | 
 | 108 |       node->logMask |= 1 << i; | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 109 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 110 |   } | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 111 | } | 
 | 112 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 113 | LIBLOG_ABI_PUBLIC int __android_log_dev_available() { | 
 | 114 |   struct android_log_transport_write* node; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 115 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 116 |   if (list_empty(&__android_log_transport_write)) { | 
 | 117 |     return kLogUninitialized; | 
 | 118 |   } | 
| Mark Salyzyn | c33103c | 2016-03-28 16:20:29 -0700 | [diff] [blame] | 119 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 120 |   write_transport_for_each(node, &__android_log_transport_write) { | 
 | 121 |     __android_log_cache_available(node); | 
 | 122 |     if (node->logMask) { | 
 | 123 |       return kLogAvailable; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 124 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 125 |   } | 
 | 126 |   return kLogNotAvailable; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 127 | } | 
| Mark Salyzyn | ba1a798 | 2016-09-13 07:28:21 -0700 | [diff] [blame] | 128 |  | 
| Dan Willemsen | 0910d2d | 2016-11-29 13:39:55 -0800 | [diff] [blame] | 129 | #if defined(__ANDROID__) | 
| Mark Salyzyn | ba1a798 | 2016-09-13 07:28:21 -0700 | [diff] [blame] | 130 | static atomic_uintptr_t tagMap; | 
 | 131 | #endif | 
 | 132 |  | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 133 | /* | 
 | 134 |  * Release any logger resources. A new log write will immediately re-acquire. | 
 | 135 |  */ | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 136 | LIBLOG_ABI_PUBLIC void __android_log_close() { | 
 | 137 |   struct android_log_transport_write* transport; | 
| Dan Willemsen | 0910d2d | 2016-11-29 13:39:55 -0800 | [diff] [blame] | 138 | #if defined(__ANDROID__) | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 139 |   EventTagMap* m; | 
| Mark Salyzyn | ba1a798 | 2016-09-13 07:28:21 -0700 | [diff] [blame] | 140 | #endif | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 141 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 142 |   __android_log_lock(); | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 143 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 144 |   write_to_log = __write_to_log_init; | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 145 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 146 |   /* | 
 | 147 |    * Threads that are actively writing at this point are not held back | 
 | 148 |    * by a lock and are at risk of dropping the messages with a return code | 
 | 149 |    * -EBADF. Prefer to return error code than add the overhead of a lock to | 
 | 150 |    * each log writing call to guarantee delivery. In addition, anyone | 
 | 151 |    * calling this is doing so to release the logging resources and shut down, | 
 | 152 |    * for them to do so with outstanding log requests in other threads is a | 
 | 153 |    * disengenuous use of this function. | 
 | 154 |    */ | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 155 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 156 |   write_transport_for_each(transport, &__android_log_persist_write) { | 
 | 157 |     if (transport->close) { | 
 | 158 |       (*transport->close)(); | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 159 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 160 |   } | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 161 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 162 |   write_transport_for_each(transport, &__android_log_transport_write) { | 
 | 163 |     if (transport->close) { | 
 | 164 |       (*transport->close)(); | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 165 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 166 |   } | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 167 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 168 |   __android_log_config_write_close(); | 
| Mark Salyzyn | 7100288 | 2016-03-08 16:18:26 -0800 | [diff] [blame] | 169 |  | 
| Dan Willemsen | 0910d2d | 2016-11-29 13:39:55 -0800 | [diff] [blame] | 170 | #if defined(__ANDROID__) | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 171 |   /* | 
 | 172 |    * Additional risk here somewhat mitigated by immediately unlock flushing | 
 | 173 |    * the processor cache. The multi-threaded race that we choose to accept, | 
 | 174 |    * to minimize locking, is an atomic_load in a writer picking up a value | 
 | 175 |    * just prior to entering this routine. There will be an use after free. | 
 | 176 |    * | 
 | 177 |    * Again, anyone calling this is doing so to release the logging resources | 
 | 178 |    * is most probably going to quiesce then shut down; or to restart after | 
 | 179 |    * a fork so the risk should be non-existent. For this reason we | 
 | 180 |    * choose a mitigation stance for efficiency instead of incuring the cost | 
 | 181 |    * of a lock for every log write. | 
 | 182 |    */ | 
 | 183 |   m = (EventTagMap*)atomic_exchange(&tagMap, (uintptr_t)0); | 
| Mark Salyzyn | ba1a798 | 2016-09-13 07:28:21 -0700 | [diff] [blame] | 184 | #endif | 
 | 185 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 186 |   __android_log_unlock(); | 
| Mark Salyzyn | ba1a798 | 2016-09-13 07:28:21 -0700 | [diff] [blame] | 187 |  | 
| Dan Willemsen | 0910d2d | 2016-11-29 13:39:55 -0800 | [diff] [blame] | 188 | #if defined(__ANDROID__) | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 189 |   if (m != (EventTagMap*)(uintptr_t)-1LL) android_closeEventTagMap(m); | 
| Mark Salyzyn | ba1a798 | 2016-09-13 07:28:21 -0700 | [diff] [blame] | 190 | #endif | 
| Mark Salyzyn | df7a4c6 | 2016-08-23 10:23:36 -0700 | [diff] [blame] | 191 | } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 192 |  | 
 | 193 | /* log_init_lock assumed */ | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 194 | static int __write_to_log_initialize() { | 
 | 195 |   struct android_log_transport_write* transport; | 
 | 196 |   struct listnode* n; | 
 | 197 |   int i = 0, ret = 0; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 198 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 199 |   __android_log_config_write(); | 
 | 200 |   write_transport_for_each_safe(transport, n, &__android_log_transport_write) { | 
 | 201 |     __android_log_cache_available(transport); | 
 | 202 |     if (!transport->logMask) { | 
 | 203 |       list_remove(&transport->node); | 
 | 204 |       continue; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 205 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 206 |     if (!transport->open || ((*transport->open)() < 0)) { | 
 | 207 |       if (transport->close) { | 
 | 208 |         (*transport->close)(); | 
 | 209 |       } | 
 | 210 |       list_remove(&transport->node); | 
 | 211 |       continue; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 212 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 213 |     ++ret; | 
 | 214 |   } | 
 | 215 |   write_transport_for_each_safe(transport, n, &__android_log_persist_write) { | 
 | 216 |     __android_log_cache_available(transport); | 
 | 217 |     if (!transport->logMask) { | 
 | 218 |       list_remove(&transport->node); | 
 | 219 |       continue; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 220 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 221 |     if (!transport->open || ((*transport->open)() < 0)) { | 
 | 222 |       if (transport->close) { | 
 | 223 |         (*transport->close)(); | 
 | 224 |       } | 
 | 225 |       list_remove(&transport->node); | 
 | 226 |       continue; | 
 | 227 |     } | 
 | 228 |     ++i; | 
 | 229 |   } | 
 | 230 |   if (!ret && !i) { | 
 | 231 |     return -ENODEV; | 
 | 232 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 233 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 234 |   return ret; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 235 | } | 
 | 236 |  | 
 | 237 | /* | 
 | 238 |  * Extract a 4-byte value from a byte stream. le32toh open coded | 
 | 239 |  */ | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 240 | static inline uint32_t get4LE(const uint8_t* src) { | 
 | 241 |   return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 242 | } | 
 | 243 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 244 | static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) { | 
 | 245 |   struct android_log_transport_write* node; | 
 | 246 |   int ret; | 
 | 247 |   struct timespec ts; | 
 | 248 |   size_t len, i; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 249 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 250 |   for (len = i = 0; i < nr; ++i) { | 
 | 251 |     len += vec[i].iov_len; | 
 | 252 |   } | 
 | 253 |   if (!len) { | 
 | 254 |     return -EINVAL; | 
 | 255 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 256 |  | 
| Dan Willemsen | 0910d2d | 2016-11-29 13:39:55 -0800 | [diff] [blame] | 257 | #if defined(__ANDROID__) | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 258 |   clock_gettime(android_log_clockid(), &ts); | 
| Mark Salyzyn | 142b43d | 2016-12-28 10:30:57 -0800 | [diff] [blame] | 259 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 260 |   if (log_id == LOG_ID_SECURITY) { | 
 | 261 |     if (vec[0].iov_len < 4) { | 
 | 262 |       return -EINVAL; | 
 | 263 |     } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 264 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 265 |     ret = check_log_uid_permissions(); | 
 | 266 |     if (ret < 0) { | 
 | 267 |       return ret; | 
 | 268 |     } | 
 | 269 |     if (!__android_log_security()) { | 
 | 270 |       /* If only we could reset downstream logd counter */ | 
 | 271 |       return -EPERM; | 
 | 272 |     } | 
 | 273 |   } else if (log_id == LOG_ID_EVENTS) { | 
 | 274 |     const char* tag; | 
 | 275 |     size_t len; | 
 | 276 |     EventTagMap *m, *f; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 277 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 278 |     if (vec[0].iov_len < 4) { | 
 | 279 |       return -EINVAL; | 
 | 280 |     } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 281 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 282 |     tag = NULL; | 
 | 283 |     len = 0; | 
 | 284 |     f = NULL; | 
 | 285 |     m = (EventTagMap*)atomic_load(&tagMap); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 286 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 287 |     if (!m) { | 
 | 288 |       ret = __android_log_trylock(); | 
 | 289 |       m = (EventTagMap*)atomic_load(&tagMap); /* trylock flush cache */ | 
 | 290 |       if (!m) { | 
 | 291 |         m = android_openEventTagMap(NULL); | 
 | 292 |         if (ret) { /* trylock failed, use local copy, mark for close */ | 
 | 293 |           f = m; | 
 | 294 |         } else { | 
 | 295 |           if (!m) { /* One chance to open map file */ | 
 | 296 |             m = (EventTagMap*)(uintptr_t)-1LL; | 
 | 297 |           } | 
 | 298 |           atomic_store(&tagMap, (uintptr_t)m); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 299 |         } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 300 |       } | 
 | 301 |       if (!ret) { /* trylock succeeded, unlock */ | 
 | 302 |         __android_log_unlock(); | 
 | 303 |       } | 
 | 304 |     } | 
 | 305 |     if (m && (m != (EventTagMap*)(uintptr_t)-1LL)) { | 
 | 306 |       tag = android_lookupEventTag_len(m, &len, get4LE(vec[0].iov_base)); | 
 | 307 |     } | 
 | 308 |     ret = __android_log_is_loggable_len(ANDROID_LOG_INFO, tag, len, | 
 | 309 |                                         ANDROID_LOG_VERBOSE); | 
 | 310 |     if (f) { /* local copy marked for close */ | 
 | 311 |       android_closeEventTagMap(f); | 
 | 312 |     } | 
 | 313 |     if (!ret) { | 
 | 314 |       return -EPERM; | 
 | 315 |     } | 
 | 316 |   } else { | 
 | 317 |     /* Validate the incoming tag, tag content can not split across iovec */ | 
 | 318 |     char prio = ANDROID_LOG_VERBOSE; | 
 | 319 |     const char* tag = vec[0].iov_base; | 
 | 320 |     size_t len = vec[0].iov_len; | 
 | 321 |     if (!tag) { | 
 | 322 |       len = 0; | 
 | 323 |     } | 
 | 324 |     if (len > 0) { | 
 | 325 |       prio = *tag; | 
 | 326 |       if (len > 1) { | 
 | 327 |         --len; | 
 | 328 |         ++tag; | 
 | 329 |       } else { | 
 | 330 |         len = vec[1].iov_len; | 
 | 331 |         tag = ((const char*)vec[1].iov_base); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 332 |         if (!tag) { | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 333 |           len = 0; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 334 |         } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 335 |       } | 
 | 336 |     } | 
 | 337 |     /* tag must be nul terminated */ | 
 | 338 |     if (tag && strnlen(tag, len) >= len) { | 
 | 339 |       tag = NULL; | 
 | 340 |     } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 341 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 342 |     if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) { | 
 | 343 |       return -EPERM; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 344 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 345 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 346 | #else | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 347 |   /* simulate clock_gettime(CLOCK_REALTIME, &ts); */ | 
 | 348 |   { | 
 | 349 |     struct timeval tv; | 
 | 350 |     gettimeofday(&tv, NULL); | 
 | 351 |     ts.tv_sec = tv.tv_sec; | 
 | 352 |     ts.tv_nsec = tv.tv_usec * 1000; | 
 | 353 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 354 | #endif | 
 | 355 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 356 |   ret = 0; | 
 | 357 |   i = 1 << log_id; | 
 | 358 |   write_transport_for_each(node, &__android_log_transport_write) { | 
 | 359 |     if (node->logMask & i) { | 
 | 360 |       ssize_t retval; | 
 | 361 |       retval = (*node->write)(log_id, &ts, vec, nr); | 
 | 362 |       if (ret >= 0) { | 
 | 363 |         ret = retval; | 
 | 364 |       } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 365 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 366 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 367 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 368 |   write_transport_for_each(node, &__android_log_persist_write) { | 
 | 369 |     if (node->logMask & i) { | 
 | 370 |       (void)(*node->write)(log_id, &ts, vec, nr); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 371 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 372 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 373 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 374 |   return ret; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 375 | } | 
 | 376 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 377 | static int __write_to_log_init(log_id_t log_id, struct iovec* vec, size_t nr) { | 
 | 378 |   __android_log_lock(); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 379 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 380 |   if (write_to_log == __write_to_log_init) { | 
 | 381 |     int ret; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 382 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 383 |     ret = __write_to_log_initialize(); | 
 | 384 |     if (ret < 0) { | 
 | 385 |       __android_log_unlock(); | 
 | 386 |       if (!list_empty(&__android_log_persist_write)) { | 
 | 387 |         __write_to_log_daemon(log_id, vec, nr); | 
 | 388 |       } | 
 | 389 |       return ret; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 390 |     } | 
 | 391 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 392 |     write_to_log = __write_to_log_daemon; | 
 | 393 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 394 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 395 |   __android_log_unlock(); | 
 | 396 |  | 
 | 397 |   return write_to_log(log_id, vec, nr); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 398 | } | 
 | 399 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 400 | LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char* tag, | 
 | 401 |                                           const char* msg) { | 
 | 402 |   return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 403 | } | 
 | 404 |  | 
 | 405 | LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio, | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 406 |                                               const char* tag, const char* msg) { | 
 | 407 |   struct iovec vec[3]; | 
 | 408 |   char tmp_tag[32]; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 409 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 410 |   if (!tag) tag = ""; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 411 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 412 |   /* XXX: This needs to go! */ | 
 | 413 |   if ((bufID != LOG_ID_RADIO) && | 
 | 414 |       (!strcmp(tag, "HTC_RIL") || | 
 | 415 |        !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */ | 
 | 416 |        !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */ | 
 | 417 |        !strcmp(tag, "AT") || !strcmp(tag, "GSM") || !strcmp(tag, "STK") || | 
 | 418 |        !strcmp(tag, "CDMA") || !strcmp(tag, "PHONE") || !strcmp(tag, "SMS"))) { | 
 | 419 |     bufID = LOG_ID_RADIO; | 
 | 420 |     /* Inform third party apps/ril/radio.. to use Rlog or RLOG */ | 
 | 421 |     snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag); | 
 | 422 |     tag = tmp_tag; | 
 | 423 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 424 |  | 
 | 425 | #if __BIONIC__ | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 426 |   if (prio == ANDROID_LOG_FATAL) { | 
 | 427 |     android_set_abort_message(msg); | 
 | 428 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 429 | #endif | 
 | 430 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 431 |   vec[0].iov_base = (unsigned char*)&prio; | 
 | 432 |   vec[0].iov_len = 1; | 
 | 433 |   vec[1].iov_base = (void*)tag; | 
 | 434 |   vec[1].iov_len = strlen(tag) + 1; | 
 | 435 |   vec[2].iov_base = (void*)msg; | 
 | 436 |   vec[2].iov_len = strlen(msg) + 1; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 437 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 438 |   return write_to_log(bufID, vec, 3); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 439 | } | 
 | 440 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 441 | LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char* tag, | 
 | 442 |                                            const char* fmt, va_list ap) { | 
 | 443 |   char buf[LOG_BUF_SIZE]; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 444 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 445 |   vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 446 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 447 |   return __android_log_write(prio, tag, buf); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 448 | } | 
 | 449 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 450 | LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char* tag, | 
 | 451 |                                           const char* fmt, ...) { | 
 | 452 |   va_list ap; | 
 | 453 |   char buf[LOG_BUF_SIZE]; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 454 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 455 |   va_start(ap, fmt); | 
 | 456 |   vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); | 
 | 457 |   va_end(ap); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 458 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 459 |   return __android_log_write(prio, tag, buf); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 460 | } | 
 | 461 |  | 
 | 462 | LIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio, | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 463 |                                               const char* tag, const char* fmt, | 
 | 464 |                                               ...) { | 
 | 465 |   va_list ap; | 
 | 466 |   char buf[LOG_BUF_SIZE]; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 467 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 468 |   va_start(ap, fmt); | 
 | 469 |   vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); | 
 | 470 |   va_end(ap); | 
 | 471 |  | 
 | 472 |   return __android_log_buf_write(bufID, prio, tag, buf); | 
 | 473 | } | 
 | 474 |  | 
 | 475 | LIBLOG_ABI_PUBLIC void __android_log_assert(const char* cond, const char* tag, | 
 | 476 |                                             const char* fmt, ...) { | 
 | 477 |   char buf[LOG_BUF_SIZE]; | 
 | 478 |  | 
 | 479 |   if (fmt) { | 
 | 480 |     va_list ap; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 481 |     va_start(ap, fmt); | 
 | 482 |     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); | 
 | 483 |     va_end(ap); | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 484 |   } else { | 
 | 485 |     /* Msg not provided, log condition.  N.B. Do not use cond directly as | 
 | 486 |      * format string as it could contain spurious '%' syntax (e.g. | 
 | 487 |      * "%d" in "blocks%devs == 0"). | 
 | 488 |      */ | 
 | 489 |     if (cond) | 
 | 490 |       snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond); | 
 | 491 |     else | 
 | 492 |       strcpy(buf, "Unspecified assertion failed"); | 
 | 493 |   } | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 494 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 495 |   // Log assertion failures to stderr for the benefit of "adb shell" users | 
 | 496 |   // and gtests (http://b/23675822). | 
 | 497 |   struct iovec iov[2] = { | 
 | 498 |     { buf, strlen(buf) }, { (char*)"\n", 1 }, | 
 | 499 |   }; | 
 | 500 |   TEMP_FAILURE_RETRY(writev(2, iov, 2)); | 
 | 501 |  | 
 | 502 |   __android_log_write(ANDROID_LOG_FATAL, tag, buf); | 
 | 503 |   abort(); /* abort so we have a chance to debug the situation */ | 
 | 504 |            /* NOTREACHED */ | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 505 | } | 
 | 506 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 507 | LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag, const void* payload, | 
 | 508 |                                            size_t len) { | 
 | 509 |   struct iovec vec[2]; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 510 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 511 |   vec[0].iov_base = &tag; | 
 | 512 |   vec[0].iov_len = sizeof(tag); | 
 | 513 |   vec[1].iov_base = (void*)payload; | 
 | 514 |   vec[1].iov_len = len; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 515 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 516 |   return write_to_log(LOG_ID_EVENTS, vec, 2); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 517 | } | 
 | 518 |  | 
 | 519 | LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag, | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 520 |                                                     const void* payload, | 
 | 521 |                                                     size_t len) { | 
 | 522 |   struct iovec vec[2]; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 523 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 524 |   vec[0].iov_base = &tag; | 
 | 525 |   vec[0].iov_len = sizeof(tag); | 
 | 526 |   vec[1].iov_base = (void*)payload; | 
 | 527 |   vec[1].iov_len = len; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 528 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 529 |   return write_to_log(LOG_ID_SECURITY, vec, 2); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 530 | } | 
 | 531 |  | 
 | 532 | /* | 
 | 533 |  * Like __android_log_bwrite, but takes the type as well.  Doesn't work | 
 | 534 |  * for the general case where we're generating lists of stuff, but very | 
 | 535 |  * handy if we just want to dump an integer into the log. | 
 | 536 |  */ | 
 | 537 | LIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type, | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 538 |                                             const void* payload, size_t len) { | 
 | 539 |   struct iovec vec[3]; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 540 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 541 |   vec[0].iov_base = &tag; | 
 | 542 |   vec[0].iov_len = sizeof(tag); | 
 | 543 |   vec[1].iov_base = &type; | 
 | 544 |   vec[1].iov_len = sizeof(type); | 
 | 545 |   vec[2].iov_base = (void*)payload; | 
 | 546 |   vec[2].iov_len = len; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 547 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 548 |   return write_to_log(LOG_ID_EVENTS, vec, 3); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 549 | } | 
 | 550 |  | 
 | 551 | /* | 
 | 552 |  * Like __android_log_bwrite, but used for writing strings to the | 
 | 553 |  * event log. | 
 | 554 |  */ | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 555 | LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char* payload) { | 
 | 556 |   struct iovec vec[4]; | 
 | 557 |   char type = EVENT_TYPE_STRING; | 
 | 558 |   uint32_t len = strlen(payload); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 559 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 560 |   vec[0].iov_base = &tag; | 
 | 561 |   vec[0].iov_len = sizeof(tag); | 
 | 562 |   vec[1].iov_base = &type; | 
 | 563 |   vec[1].iov_len = sizeof(type); | 
 | 564 |   vec[2].iov_base = &len; | 
 | 565 |   vec[2].iov_len = sizeof(len); | 
 | 566 |   vec[3].iov_base = (void*)payload; | 
 | 567 |   vec[3].iov_len = len; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 568 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 569 |   return write_to_log(LOG_ID_EVENTS, vec, 4); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 570 | } | 
 | 571 |  | 
 | 572 | /* | 
 | 573 |  * Like __android_log_security_bwrite, but used for writing strings to the | 
 | 574 |  * security log. | 
 | 575 |  */ | 
 | 576 | LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag, | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 577 |                                                      const char* payload) { | 
 | 578 |   struct iovec vec[4]; | 
 | 579 |   char type = EVENT_TYPE_STRING; | 
 | 580 |   uint32_t len = strlen(payload); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 581 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 582 |   vec[0].iov_base = &tag; | 
 | 583 |   vec[0].iov_len = sizeof(tag); | 
 | 584 |   vec[1].iov_base = &type; | 
 | 585 |   vec[1].iov_len = sizeof(type); | 
 | 586 |   vec[2].iov_base = &len; | 
 | 587 |   vec[2].iov_len = sizeof(len); | 
 | 588 |   vec[3].iov_base = (void*)payload; | 
 | 589 |   vec[3].iov_len = len; | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 590 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 591 |   return write_to_log(LOG_ID_SECURITY, vec, 4); | 
| Mark Salyzyn | 018a96d | 2016-03-01 13:45:42 -0800 | [diff] [blame] | 592 | } | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 593 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 594 | static int __write_to_log_null(log_id_t log_id, struct iovec* vec, size_t nr) { | 
 | 595 |   size_t len, i; | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 596 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 597 |   if ((log_id < LOG_ID_MIN) || (log_id >= LOG_ID_MAX)) { | 
 | 598 |     return -EINVAL; | 
 | 599 |   } | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 600 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 601 |   for (len = i = 0; i < nr; ++i) { | 
 | 602 |     len += vec[i].iov_len; | 
 | 603 |   } | 
 | 604 |   if (!len) { | 
 | 605 |     return -EINVAL; | 
 | 606 |   } | 
 | 607 |   return len; | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 608 | } | 
 | 609 |  | 
 | 610 | /* Following functions need access to our internal write_to_log status */ | 
 | 611 |  | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 612 | LIBLOG_HIDDEN int __android_log_transport; | 
| Mark Salyzyn | 7100288 | 2016-03-08 16:18:26 -0800 | [diff] [blame] | 613 |  | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 614 | LIBLOG_ABI_PUBLIC int android_set_log_transport(int transport_flag) { | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 615 |   int retval; | 
| Mark Salyzyn | 7100288 | 2016-03-08 16:18:26 -0800 | [diff] [blame] | 616 |  | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 617 |   if (transport_flag < 0) { | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 618 |     return -EINVAL; | 
 | 619 |   } | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 620 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 621 |   retval = LOGGER_NULL; | 
| Mark Salyzyn | 7100288 | 2016-03-08 16:18:26 -0800 | [diff] [blame] | 622 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 623 |   __android_log_lock(); | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 624 |  | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 625 |   if (transport_flag & LOGGER_NULL) { | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 626 |     write_to_log = __write_to_log_null; | 
| Mark Salyzyn | 7100288 | 2016-03-08 16:18:26 -0800 | [diff] [blame] | 627 |  | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 628 |     __android_log_unlock(); | 
 | 629 |  | 
| Mark Salyzyn | 7100288 | 2016-03-08 16:18:26 -0800 | [diff] [blame] | 630 |     return retval; | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 631 |   } | 
 | 632 |  | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 633 |   __android_log_transport &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR; | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 634 |  | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 635 |   transport_flag &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR; | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 636 |  | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 637 |   if (__android_log_transport != transport_flag) { | 
 | 638 |     __android_log_transport = transport_flag; | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 639 |     __android_log_config_write_close(); | 
 | 640 |     __android_log_config_read_close(); | 
 | 641 |  | 
 | 642 |     write_to_log = __write_to_log_init; | 
 | 643 |     /* generically we only expect these two values for write_to_log */ | 
 | 644 |   } else if ((write_to_log != __write_to_log_init) && | 
 | 645 |              (write_to_log != __write_to_log_daemon)) { | 
 | 646 |     write_to_log = __write_to_log_init; | 
 | 647 |   } | 
 | 648 |  | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 649 |   retval = __android_log_transport; | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 650 |  | 
 | 651 |   __android_log_unlock(); | 
 | 652 |  | 
 | 653 |   return retval; | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 654 | } | 
 | 655 |  | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 656 | LIBLOG_ABI_PUBLIC int android_get_log_transport() { | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 657 |   int ret = LOGGER_DEFAULT; | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 658 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 659 |   __android_log_lock(); | 
 | 660 |   if (write_to_log == __write_to_log_null) { | 
 | 661 |     ret = LOGGER_NULL; | 
 | 662 |   } else { | 
| Mark Salyzyn | 81321a7 | 2017-03-09 07:28:29 -0800 | [diff] [blame] | 663 |     __android_log_transport &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR; | 
 | 664 |     ret = __android_log_transport; | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 665 |     if ((write_to_log != __write_to_log_init) && | 
 | 666 |         (write_to_log != __write_to_log_daemon)) { | 
 | 667 |       ret = -EINVAL; | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 668 |     } | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 669 |   } | 
 | 670 |   __android_log_unlock(); | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 671 |  | 
| Mark Salyzyn | 2ed51d7 | 2017-03-09 08:09:43 -0800 | [diff] [blame] | 672 |   return ret; | 
| Mark Salyzyn | 850d06e | 2015-02-04 12:39:57 -0800 | [diff] [blame] | 673 | } |