blob: bd8d5af95940f2b367d843d8778eb624a0825dd1 [file] [log] [blame]
Mark Salyzyn95687052014-10-02 11:12:28 -07001/*
2** Copyright 2014, 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 <ctype.h>
Mark Salyzync1584562015-03-12 15:46:29 -070018#include <pthread.h>
19#include <stdlib.h>
Mark Salyzyn95687052014-10-02 11:12:28 -070020#include <string.h>
Mark Salyzync1584562015-03-12 15:46:29 -070021#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
22#include <sys/_system_properties.h>
Mark Salyzyn95687052014-10-02 11:12:28 -070023
24#include <android/log.h>
25
Mark Salyzynfacf94c2016-03-01 13:45:42 -080026#include "log_portability.h"
Mark Salyzyn6d753fa2016-03-10 08:25:33 -080027
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -080028static pthread_mutex_t lock_loggable = PTHREAD_MUTEX_INITIALIZER;
29
Mark Salyzyna67d8a52015-12-21 12:32:48 -080030static int lock()
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -080031{
32 /*
33 * If we trigger a signal handler in the middle of locked activity and the
34 * signal handler logs a message, we could get into a deadlock state.
35 */
Mark Salyzyna67d8a52015-12-21 12:32:48 -080036 /*
37 * Any contention, and we can turn around and use the non-cached method
38 * in less time than the system call associated with a mutex to deal with
39 * the contention.
40 */
41 return pthread_mutex_trylock(&lock_loggable);
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -080042}
43
44static void unlock()
45{
46 pthread_mutex_unlock(&lock_loggable);
47}
48
Mark Salyzync1584562015-03-12 15:46:29 -070049struct cache {
50 const prop_info *pinfo;
51 uint32_t serial;
Mark Salyzynb004a7f2015-12-08 14:52:11 -080052 unsigned char c;
Mark Salyzync1584562015-03-12 15:46:29 -070053};
54
Mark Salyzyna67d8a52015-12-21 12:32:48 -080055static int check_cache(struct cache *cache)
56{
57 return cache->pinfo
58 && __system_property_serial(cache->pinfo) != cache->serial;
59}
60
Mark Salyzynffbd86f2015-12-04 10:59:45 -080061#define BOOLEAN_TRUE 0xFF
62#define BOOLEAN_FALSE 0xFE
63
Mark Salyzync1584562015-03-12 15:46:29 -070064static void refresh_cache(struct cache *cache, const char *key)
Mark Salyzyn95687052014-10-02 11:12:28 -070065{
66 char buf[PROP_VALUE_MAX];
67
Mark Salyzync1584562015-03-12 15:46:29 -070068 if (!cache->pinfo) {
69 cache->pinfo = __system_property_find(key);
70 if (!cache->pinfo) {
71 return;
72 }
Mark Salyzyn95687052014-10-02 11:12:28 -070073 }
Mark Salyzyn504daa62016-04-14 15:31:56 -070074 cache->serial = __system_property_serial(cache->pinfo);
Mark Salyzync1584562015-03-12 15:46:29 -070075 __system_property_read(cache->pinfo, 0, buf);
Mark Salyzynffbd86f2015-12-04 10:59:45 -080076 switch(buf[0]) {
77 case 't': case 'T':
78 cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE;
79 break;
80 case 'f': case 'F':
81 cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE;
82 break;
83 default:
84 cache->c = buf[0];
85 }
Mark Salyzync1584562015-03-12 15:46:29 -070086}
Mark Salyzyn95687052014-10-02 11:12:28 -070087
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -080088static int __android_log_level(const char *tag, int default_prio)
Mark Salyzync1584562015-03-12 15:46:29 -070089{
90 /* sizeof() is used on this array below */
91 static const char log_namespace[] = "persist.log.tag.";
92 static const size_t base_offset = 8; /* skip "persist." */
93 /* calculate the size of our key temporary buffer */
94 const size_t taglen = (tag && *tag) ? strlen(tag) : 0;
95 /* sizeof(log_namespace) = strlen(log_namespace) + 1 */
Mark Salyzyna67d8a52015-12-21 12:32:48 -080096 char key[sizeof(log_namespace) + taglen]; /* may be > PROPERTY_KEY_MAX */
Mark Salyzync1584562015-03-12 15:46:29 -070097 char *kp;
98 size_t i;
99 char c = 0;
100 /*
101 * Single layer cache of four properties. Priorities are:
102 * log.tag.<tag>
103 * persist.log.tag.<tag>
104 * log.tag
105 * persist.log.tag
106 * Where the missing tag matches all tags and becomes the
107 * system global default. We do not support ro.log.tag* .
108 */
Colin Cross7a106f72016-01-29 16:21:31 -0800109 static char last_tag[PROP_NAME_MAX];
Mark Salyzync1584562015-03-12 15:46:29 -0700110 static uint32_t global_serial;
Mark Salyzyn31ca3c32015-12-22 10:49:02 -0800111 /* some compilers erroneously see uninitialized use. !not_locked */
112 uint32_t current_global_serial = 0;
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800113 static struct cache tag_cache[2];
114 static struct cache global_cache[2];
115 int change_detected;
116 int global_change_detected;
117 int not_locked;
Mark Salyzync1584562015-03-12 15:46:29 -0700118
119 strcpy(key, log_namespace);
120
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800121 global_change_detected = change_detected = not_locked = lock();
Mark Salyzync1584562015-03-12 15:46:29 -0700122
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800123 if (!not_locked) {
124 /*
125 * check all known serial numbers to changes.
126 */
127 for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
128 if (check_cache(&tag_cache[i])) {
129 change_detected = 1;
130 }
131 }
132 for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
133 if (check_cache(&global_cache[i])) {
134 global_change_detected = 1;
135 }
136 }
137
138 current_global_serial = __system_property_area_serial();
139 if (current_global_serial != global_serial) {
140 change_detected = 1;
141 global_change_detected = 1;
142 }
143 }
Mark Salyzync1584562015-03-12 15:46:29 -0700144
145 if (taglen) {
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800146 int local_change_detected = change_detected;
147 if (!not_locked) {
Colin Cross7a106f72016-01-29 16:21:31 -0800148 if (!last_tag[0]
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800149 || (last_tag[0] != tag[0])
Colin Cross7a106f72016-01-29 16:21:31 -0800150 || strncmp(last_tag + 1, tag + 1, sizeof(last_tag) - 1)) {
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800151 /* invalidate log.tag.<tag> cache */
152 for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
153 tag_cache[i].pinfo = NULL;
154 tag_cache[i].c = '\0';
155 }
Colin Cross7a106f72016-01-29 16:21:31 -0800156 last_tag[0] = '\0';
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800157 local_change_detected = 1;
Mark Salyzync1584562015-03-12 15:46:29 -0700158 }
Colin Cross7a106f72016-01-29 16:21:31 -0800159 if (!last_tag[0]) {
160 strncpy(last_tag, tag, sizeof(last_tag));
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800161 }
Mark Salyzync1584562015-03-12 15:46:29 -0700162 }
Mark Salyzyn95687052014-10-02 11:12:28 -0700163 strcpy(key + sizeof(log_namespace) - 1, tag);
164
Mark Salyzync1584562015-03-12 15:46:29 -0700165 kp = key;
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800166 for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) {
167 struct cache *cache = &tag_cache[i];
168 struct cache temp_cache;
169
170 if (not_locked) {
171 temp_cache.pinfo = NULL;
172 temp_cache.c = '\0';
173 cache = &temp_cache;
174 }
175 if (local_change_detected) {
176 refresh_cache(cache, kp);
Mark Salyzync1584562015-03-12 15:46:29 -0700177 }
178
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800179 if (cache->c) {
180 c = cache->c;
Mark Salyzync1584562015-03-12 15:46:29 -0700181 break;
182 }
183
184 kp = key + base_offset;
Mark Salyzyn1f028b22014-10-08 15:58:40 -0700185 }
Mark Salyzyn95687052014-10-02 11:12:28 -0700186 }
Mark Salyzync1584562015-03-12 15:46:29 -0700187
188 switch (toupper(c)) { /* if invalid, resort to global */
189 case 'V':
190 case 'D':
191 case 'I':
192 case 'W':
193 case 'E':
194 case 'F': /* Not officially supported */
195 case 'A':
196 case 'S':
Mark Salyzynffbd86f2015-12-04 10:59:45 -0800197 case BOOLEAN_FALSE: /* Not officially supported */
Mark Salyzync1584562015-03-12 15:46:29 -0700198 break;
199 default:
200 /* clear '.' after log.tag */
201 key[sizeof(log_namespace) - 2] = '\0';
202
203 kp = key;
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800204 for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) {
205 struct cache *cache = &global_cache[i];
206 struct cache temp_cache;
207
208 if (not_locked) {
209 temp_cache = *cache;
210 if (temp_cache.pinfo != cache->pinfo) { /* check atomic */
211 temp_cache.pinfo = NULL;
212 temp_cache.c = '\0';
213 }
214 cache = &temp_cache;
215 }
216 if (global_change_detected) {
217 refresh_cache(cache, kp);
Mark Salyzync1584562015-03-12 15:46:29 -0700218 }
219
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800220 if (cache->c) {
221 c = cache->c;
Mark Salyzync1584562015-03-12 15:46:29 -0700222 break;
223 }
224
225 kp = key + base_offset;
226 }
227 break;
228 }
229
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800230 if (!not_locked) {
231 global_serial = current_global_serial;
232 unlock();
233 }
Mark Salyzync1584562015-03-12 15:46:29 -0700234
235 switch (toupper(c)) {
236 case 'V': return ANDROID_LOG_VERBOSE;
237 case 'D': return ANDROID_LOG_DEBUG;
238 case 'I': return ANDROID_LOG_INFO;
239 case 'W': return ANDROID_LOG_WARN;
240 case 'E': return ANDROID_LOG_ERROR;
241 case 'F': /* FALLTHRU */ /* Not officially supported */
242 case 'A': return ANDROID_LOG_FATAL;
Mark Salyzynffbd86f2015-12-04 10:59:45 -0800243 case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */
Mark Salyzync1584562015-03-12 15:46:29 -0700244 case 'S': return -1; /* ANDROID_LOG_SUPPRESS */
Mark Salyzyn95687052014-10-02 11:12:28 -0700245 }
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800246 return default_prio;
Mark Salyzyn95687052014-10-02 11:12:28 -0700247}
248
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800249LIBLOG_ABI_PUBLIC int __android_log_is_loggable(int prio, const char *tag,
250 int default_prio)
Mark Salyzyn95687052014-10-02 11:12:28 -0700251{
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800252 int logLevel = __android_log_level(tag, default_prio);
Mark Salyzyn95687052014-10-02 11:12:28 -0700253 return logLevel >= 0 && prio >= logLevel;
254}
Mark Salyzyn500afc72015-09-08 08:32:01 -0700255
Mark Salyzynf58e58a2016-03-25 15:50:46 -0700256LIBLOG_HIDDEN int __android_log_is_debuggable()
257{
258 static uint32_t serial;
259 static struct cache tag_cache;
260 static const char key[] = "ro.debuggable";
261 int ret;
262
263 if (tag_cache.c) { /* ro property does not change after set */
264 ret = tag_cache.c == '1';
265 } else if (lock()) {
266 struct cache temp_cache = { NULL, -1, '\0' };
267 refresh_cache(&temp_cache, key);
268 ret = temp_cache.c == '1';
269 } else {
270 int change_detected = check_cache(&tag_cache);
271 uint32_t current_serial = __system_property_area_serial();
272 if (current_serial != serial) {
273 change_detected = 1;
274 }
275 if (change_detected) {
276 refresh_cache(&tag_cache, key);
277 serial = current_serial;
278 }
279 ret = tag_cache.c == '1';
280
281 unlock();
282 }
283
284 return ret;
285}
286
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800287/*
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800288 * For properties that are read often, but generally remain constant.
289 * Since a change is rare, we will accept a trylock failure gracefully.
290 * Use a separate lock from is_loggable to keep contention down b/25563384.
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800291 */
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800292struct cache2 {
293 pthread_mutex_t lock;
294 uint32_t serial;
295 const char *key_persist;
296 struct cache cache_persist;
297 const char *key_ro;
298 struct cache cache_ro;
299 unsigned char (*const evaluate)(const struct cache2 *self);
300};
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800301
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800302static inline unsigned char do_cache2(struct cache2 *self)
Mark Salyzyn500afc72015-09-08 08:32:01 -0700303{
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800304 uint32_t current_serial;
305 int change_detected;
306 unsigned char c;
Mark Salyzyn500afc72015-09-08 08:32:01 -0700307
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800308 if (pthread_mutex_trylock(&self->lock)) {
Mark Salyzyn2d2e0a52015-11-06 12:26:52 -0800309 /* We are willing to accept some race in this context */
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800310 return self->evaluate(self);
Mark Salyzyn500afc72015-09-08 08:32:01 -0700311 }
Mark Salyzyn500afc72015-09-08 08:32:01 -0700312
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800313 change_detected = check_cache(&self->cache_persist)
314 || check_cache(&self->cache_ro);
315 current_serial = __system_property_area_serial();
316 if (current_serial != self->serial) {
317 change_detected = 1;
318 }
319 if (change_detected) {
320 refresh_cache(&self->cache_persist, self->key_persist);
321 refresh_cache(&self->cache_ro, self->key_ro);
322 self->serial = current_serial;
323 }
324 c = self->evaluate(self);
325
326 pthread_mutex_unlock(&self->lock);
327
328 return c;
329}
330
331static unsigned char evaluate_persist_ro(const struct cache2 *self)
332{
333 unsigned char c = self->cache_persist.c;
334
335 if (c) {
336 return c;
337 }
338
339 return self->cache_ro.c;
Mark Salyzyn500afc72015-09-08 08:32:01 -0700340}
Mark Salyzynffbd86f2015-12-04 10:59:45 -0800341
342/*
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800343 * Timestamp state generally remains constant, but can change at any time
344 * to handle developer requirements.
Mark Salyzynffbd86f2015-12-04 10:59:45 -0800345 */
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800346LIBLOG_ABI_PUBLIC clockid_t android_log_clockid()
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800347{
348 static struct cache2 clockid = {
349 PTHREAD_MUTEX_INITIALIZER,
350 0,
351 "persist.logd.timestamp",
352 { NULL, -1, '\0' },
353 "ro.logd.timestamp",
354 { NULL, -1, '\0' },
355 evaluate_persist_ro
356 };
357
358 return (tolower(do_cache2(&clockid)) == 'm')
359 ? CLOCK_MONOTONIC
360 : CLOCK_REALTIME;
361}
362
363/*
364 * Security state generally remains constant, but the DO must be able
365 * to turn off logging should it become spammy after an attack is detected.
366 */
367static unsigned char evaluate_security(const struct cache2 *self)
368{
369 unsigned char c = self->cache_ro.c;
370
371 return (c != BOOLEAN_FALSE) && c && (self->cache_persist.c == BOOLEAN_TRUE);
372}
Mark Salyzynffbd86f2015-12-04 10:59:45 -0800373
Mark Salyzyn6d753fa2016-03-10 08:25:33 -0800374LIBLOG_ABI_PUBLIC int __android_log_security()
Mark Salyzynffbd86f2015-12-04 10:59:45 -0800375{
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800376 static struct cache2 security = {
377 PTHREAD_MUTEX_INITIALIZER,
378 0,
379 "persist.logd.security",
380 { NULL, -1, BOOLEAN_FALSE },
381 "ro.device_owner",
382 { NULL, -1, BOOLEAN_FALSE },
383 evaluate_security
384 };
Mark Salyzynffbd86f2015-12-04 10:59:45 -0800385
Mark Salyzyna67d8a52015-12-21 12:32:48 -0800386 return do_cache2(&security);
Mark Salyzynffbd86f2015-12-04 10:59:45 -0800387}