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