summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Salyzyn2016-08-11 10:02:06 -0500
committerMark Salyzyn2017-03-27 15:32:57 -0500
commit0484b3b5757594a43c6b646824b44643d2a007de (patch)
tree813567ef4a12225062958bd807356789f0159d18 /logd/LogKlog.cpp
parent784c85178547897f10582bdc688f78fbe7f7e0ca (diff)
downloadplatform-system-core-0484b3b5757594a43c6b646824b44643d2a007de.tar.gz
platform-system-core-0484b3b5757594a43c6b646824b44643d2a007de.tar.xz
platform-system-core-0484b3b5757594a43c6b646824b44643d2a007de.zip
logd: ASAN cleansing
A mixture of fixes and cleanup for LogKlog.cpp and friends. - sscanf calls strlen. Check if the string is missing a nul terminator, if it is, do not call sscanf. - replace NULL with nullptr for stronger typechecking. - pass by reference for simpler code. - Use ssize_t where possible to check for negative values. - fix FastCmp to add some validity checking since ASAN reports that callers are not making sure pre-conditions are met. - add fasticmp templates for completeness. - if the buffer is too small to contain a meaningful time, do not call down to log_time::strptime() because it does not limit its accesses to the buffer boundaries, instead stopping at a terminating nul or invalid match. - move strnstr to LogUtils.h, drop size checking of needle and clearly report the list of needles used with android::strnstr - replace 'sizeof(static const char[]) - 1' with strlen. Test: gTest liblog-unit-test, logd-unit-tests & logcat-unit-tests Bug: 30792935 Bug: 36536248 Bug: 35468874 Bug: 34949125 Bug: 34606909 Bug: 36075298 Bug: 36608728 Change-Id: I161bf03ba029050e809b31cceef03f729d318866
Diffstat (limited to 'logd/LogKlog.cpp')
-rw-r--r--logd/LogKlog.cpp329
1 files changed, 154 insertions, 175 deletions
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 9dfa14ed3..d23254d37 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -37,46 +37,49 @@
37 37
38static const char priority_message[] = { KMSG_PRIORITY(LOG_INFO), '\0' }; 38static const char priority_message[] = { KMSG_PRIORITY(LOG_INFO), '\0' };
39 39
40// List of the _only_ needles we supply here to android::strnstr
41static const char suspendStr[] = "PM: suspend entry ";
42static const char resumeStr[] = "PM: suspend exit ";
43static const char suspendedStr[] = "Suspended for ";
44static const char healthdStr[] = "healthd";
45static const char batteryStr[] = ": battery ";
46static const char auditStr[] = " audit(";
47static const char klogdStr[] = "logd.klogd: ";
48
40// Parsing is hard 49// Parsing is hard
41 50
42// called if we see a '<', s is the next character, returns pointer after '>' 51// called if we see a '<', s is the next character, returns pointer after '>'
43static char* is_prio(char* s, size_t len) { 52static char* is_prio(char* s, ssize_t len) {
44 if (!len || !isdigit(*s++)) { 53 if ((len <= 0) || !isdigit(*s++)) return nullptr;
45 return NULL;
46 }
47 --len; 54 --len;
48 static const size_t max_prio_len = (len < 4) ? len : 4; 55 static const size_t max_prio_len = (len < 4) ? len : 4;
49 size_t priolen = 0; 56 size_t priolen = 0;
50 char c; 57 char c;
51 while (((c = *s++)) && (++priolen <= max_prio_len)) { 58 while (((c = *s++)) && (++priolen <= max_prio_len)) {
52 if (!isdigit(c)) { 59 if (!isdigit(c)) return ((c == '>') && (*s == '[')) ? s : nullptr;
53 return ((c == '>') && (*s == '[')) ? s : NULL;
54 }
55 } 60 }
56 return NULL; 61 return nullptr;
57} 62}
58 63
59// called if we see a '[', s is the next character, returns pointer after ']' 64// called if we see a '[', s is the next character, returns pointer after ']'
60static char* is_timestamp(char* s, size_t len) { 65static char* is_timestamp(char* s, ssize_t len) {
61 while (len && (*s == ' ')) { 66 while ((len > 0) && (*s == ' ')) {
62 ++s; 67 ++s;
63 --len; 68 --len;
64 } 69 }
65 if (!len || !isdigit(*s++)) { 70 if ((len <= 0) || !isdigit(*s++)) return nullptr;
66 return NULL;
67 }
68 --len; 71 --len;
69 bool first_period = true; 72 bool first_period = true;
70 char c; 73 char c;
71 while (len && ((c = *s++))) { 74 while ((len > 0) && ((c = *s++))) {
72 --len; 75 --len;
73 if ((c == '.') && first_period) { 76 if ((c == '.') && first_period) {
74 first_period = false; 77 first_period = false;
75 } else if (!isdigit(c)) { 78 } else if (!isdigit(c)) {
76 return ((c == ']') && !first_period && (*s == ' ')) ? s : NULL; 79 return ((c == ']') && !first_period && (*s == ' ')) ? s : nullptr;
77 } 80 }
78 } 81 }
79 return NULL; 82 return nullptr;
80} 83}
81 84
82// Like strtok_r with "\r\n" except that we look for log signatures (regex) 85// Like strtok_r with "\r\n" except that we look for log signatures (regex)
@@ -93,96 +96,82 @@ static char* is_timestamp(char* s, size_t len) {
93// space is one more than <digit> of 9 96// space is one more than <digit> of 9
94#define OPEN_BRACKET_SPACE ((char)(OPEN_BRACKET_SIG | 10)) 97#define OPEN_BRACKET_SPACE ((char)(OPEN_BRACKET_SIG | 10))
95 98
96char* log_strntok_r(char* s, size_t* len, char** last, size_t* sublen) { 99char* android::log_strntok_r(char* s, ssize_t& len, char*& last,
97 *sublen = 0; 100 ssize_t& sublen) {
98 if (!*len) { 101 sublen = 0;
99 return NULL; 102 if (len <= 0) return nullptr;
100 }
101 if (!s) { 103 if (!s) {
102 if (!(s = *last)) { 104 if (!(s = last)) return nullptr;
103 return NULL;
104 }
105 // fixup for log signature split <, 105 // fixup for log signature split <,
106 // LESS_THAN_SIG + <digit> 106 // LESS_THAN_SIG + <digit>
107 if ((*s & SIGNATURE_MASK) == LESS_THAN_SIG) { 107 if ((*s & SIGNATURE_MASK) == LESS_THAN_SIG) {
108 *s = (*s & ~SIGNATURE_MASK) + '0'; 108 *s = (*s & ~SIGNATURE_MASK) + '0';
109 *--s = '<'; 109 *--s = '<';
110 ++*len; 110 ++len;
111 } 111 }
112 // fixup for log signature split [, 112 // fixup for log signature split [,
113 // OPEN_BRACKET_SPACE is space, OPEN_BRACKET_SIG + <digit> 113 // OPEN_BRACKET_SPACE is space, OPEN_BRACKET_SIG + <digit>
114 if ((*s & SIGNATURE_MASK) == OPEN_BRACKET_SIG) { 114 if ((*s & SIGNATURE_MASK) == OPEN_BRACKET_SIG) {
115 if (*s == OPEN_BRACKET_SPACE) { 115 *s = (*s == OPEN_BRACKET_SPACE) ? ' ' : (*s & ~SIGNATURE_MASK) + '0';
116 *s = ' ';
117 } else {
118 *s = (*s & ~SIGNATURE_MASK) + '0';
119 }
120 *--s = '['; 116 *--s = '[';
121 ++*len; 117 ++len;
122 } 118 }
123 } 119 }
124 120
125 while (*len && ((*s == '\r') || (*s == '\n'))) { 121 while ((len > 0) && ((*s == '\r') || (*s == '\n'))) {
126 ++s; 122 ++s;
127 --*len; 123 --len;
128 } 124 }
129 125
130 if (!*len) { 126 if (len <= 0) return last = nullptr;
131 *last = NULL;
132 return NULL;
133 }
134 char *peek, *tok = s; 127 char *peek, *tok = s;
135 128
136 for (;;) { 129 for (;;) {
137 if (*len == 0) { 130 if (len <= 0) {
138 *last = NULL; 131 last = nullptr;
139 return tok; 132 return tok;
140 } 133 }
141 char c = *s++; 134 char c = *s++;
142 --*len; 135 --len;
143 size_t adjust; 136 ssize_t adjust;
144 switch (c) { 137 switch (c) {
145 case '\r': 138 case '\r':
146 case '\n': 139 case '\n':
147 s[-1] = '\0'; 140 s[-1] = '\0';
148 *last = s; 141 last = s;
149 return tok; 142 return tok;
150 143
151 case '<': 144 case '<':
152 peek = is_prio(s, *len); 145 peek = is_prio(s, len);
153 if (!peek) { 146 if (!peek) break;
154 break;
155 }
156 if (s != (tok + 1)) { // not first? 147 if (s != (tok + 1)) { // not first?
157 s[-1] = '\0'; 148 s[-1] = '\0';
158 *s &= ~SIGNATURE_MASK; 149 *s &= ~SIGNATURE_MASK;
159 *s |= LESS_THAN_SIG; // signature for '<' 150 *s |= LESS_THAN_SIG; // signature for '<'
160 *last = s; 151 last = s;
161 return tok; 152 return tok;
162 } 153 }
163 adjust = peek - s; 154 adjust = peek - s;
164 if (adjust > *len) { 155 if (adjust > len) {
165 adjust = *len; 156 adjust = len;
166 } 157 }
167 *sublen += adjust; 158 sublen += adjust;
168 *len -= adjust; 159 len -= adjust;
169 s = peek; 160 s = peek;
170 if ((*s == '[') && ((peek = is_timestamp(s + 1, *len - 1)))) { 161 if ((*s == '[') && ((peek = is_timestamp(s + 1, len - 1)))) {
171 adjust = peek - s; 162 adjust = peek - s;
172 if (adjust > *len) { 163 if (adjust > len) {
173 adjust = *len; 164 adjust = len;
174 } 165 }
175 *sublen += adjust; 166 sublen += adjust;
176 *len -= adjust; 167 len -= adjust;
177 s = peek; 168 s = peek;
178 } 169 }
179 break; 170 break;
180 171
181 case '[': 172 case '[':
182 peek = is_timestamp(s, *len); 173 peek = is_timestamp(s, len);
183 if (!peek) { 174 if (!peek) break;
184 break;
185 }
186 if (s != (tok + 1)) { // not first? 175 if (s != (tok + 1)) { // not first?
187 s[-1] = '\0'; 176 s[-1] = '\0';
188 if (*s == ' ') { 177 if (*s == ' ') {
@@ -191,19 +180,19 @@ char* log_strntok_r(char* s, size_t* len, char** last, size_t* sublen) {
191 *s &= ~SIGNATURE_MASK; 180 *s &= ~SIGNATURE_MASK;
192 *s |= OPEN_BRACKET_SIG; // signature for '[' 181 *s |= OPEN_BRACKET_SIG; // signature for '['
193 } 182 }
194 *last = s; 183 last = s;
195 return tok; 184 return tok;
196 } 185 }
197 adjust = peek - s; 186 adjust = peek - s;
198 if (adjust > *len) { 187 if (adjust > len) {
199 adjust = *len; 188 adjust = len;
200 } 189 }
201 *sublen += adjust; 190 sublen += adjust;
202 *len -= adjust; 191 len -= adjust;
203 s = peek; 192 s = peek;
204 break; 193 break;
205 } 194 }
206 ++*sublen; 195 ++sublen;
207 } 196 }
208 // NOTREACHED 197 // NOTREACHED
209} 198}
@@ -222,9 +211,10 @@ LogKlog::LogKlog(LogBuffer* buf, LogReader* reader, int fdWrite, int fdRead,
222 initialized(false), 211 initialized(false),
223 enableLogging(true), 212 enableLogging(true),
224 auditd(auditd) { 213 auditd(auditd) {
225 static const char klogd_message[] = "%slogd.klogd: %" PRIu64 "\n"; 214 static const char klogd_message[] = "%s%s%" PRIu64 "\n";
226 char buffer[sizeof(priority_message) + sizeof(klogd_message) + 20 - 4]; 215 char buffer[strlen(priority_message) + strlen(klogdStr) +
227 snprintf(buffer, sizeof(buffer), klogd_message, priority_message, 216 strlen(klogd_message) + 20];
217 snprintf(buffer, sizeof(buffer), klogd_message, priority_message, klogdStr,
228 signature.nsec()); 218 signature.nsec());
229 write(fdWrite, buffer, strlen(buffer)); 219 write(fdWrite, buffer, strlen(buffer));
230} 220}
@@ -237,15 +227,15 @@ bool LogKlog::onDataAvailable(SocketClient* cli) {
237 } 227 }
238 228
239 char buffer[LOGGER_ENTRY_MAX_PAYLOAD]; 229 char buffer[LOGGER_ENTRY_MAX_PAYLOAD];
240 size_t len = 0; 230 ssize_t len = 0;
241 231
242 for (;;) { 232 for (;;) {
243 ssize_t retval = 0; 233 ssize_t retval = 0;
244 if ((sizeof(buffer) - 1 - len) > 0) { 234 if (len < (ssize_t)(sizeof(buffer) - 1)) {
245 retval = 235 retval =
246 read(cli->getSocket(), buffer + len, sizeof(buffer) - 1 - len); 236 read(cli->getSocket(), buffer + len, sizeof(buffer) - 1 - len);
247 } 237 }
248 if ((retval == 0) && (len == 0)) { 238 if ((retval == 0) && (len <= 0)) {
249 break; 239 break;
250 } 240 }
251 if (retval < 0) { 241 if (retval < 0) {
@@ -255,15 +245,16 @@ bool LogKlog::onDataAvailable(SocketClient* cli) {
255 bool full = len == (sizeof(buffer) - 1); 245 bool full = len == (sizeof(buffer) - 1);
256 char* ep = buffer + len; 246 char* ep = buffer + len;
257 *ep = '\0'; 247 *ep = '\0';
258 size_t sublen; 248 ssize_t sublen;
259 for (char *ptr = NULL, *tok = buffer; 249 for (char *ptr = nullptr, *tok = buffer;
260 ((tok = log_strntok_r(tok, &len, &ptr, &sublen))); tok = NULL) { 250 !!(tok = android::log_strntok_r(tok, len, ptr, sublen));
251 tok = nullptr) {
261 if (((tok + sublen) >= ep) && (retval != 0) && full) { 252 if (((tok + sublen) >= ep) && (retval != 0) && full) {
262 memmove(buffer, tok, sublen); 253 if (sublen > 0) memmove(buffer, tok, sublen);
263 len = sublen; 254 len = sublen;
264 break; 255 break;
265 } 256 }
266 if (*tok) { 257 if ((sublen > 0) && *tok) {
267 log(tok, sublen); 258 log(tok, sublen);
268 } 259 }
269 } 260 }
@@ -273,9 +264,12 @@ bool LogKlog::onDataAvailable(SocketClient* cli) {
273} 264}
274 265
275void LogKlog::calculateCorrection(const log_time& monotonic, 266void LogKlog::calculateCorrection(const log_time& monotonic,
276 const char* real_string, size_t len) { 267 const char* real_string, ssize_t len) {
268 static const char real_format[] = "%Y-%m-%d %H:%M:%S.%09q UTC";
269 if (len < (ssize_t)(strlen(real_format) + 5)) return;
270
277 log_time real; 271 log_time real;
278 const char* ep = real.strptime(real_string, "%Y-%m-%d %H:%M:%S.%09q UTC"); 272 const char* ep = real.strptime(real_string, real_format);
279 if (!ep || (ep > &real_string[len]) || (real > log_time(CLOCK_REALTIME))) { 273 if (!ep || (ep > &real_string[len]) || (real > log_time(CLOCK_REALTIME))) {
280 return; 274 return;
281 } 275 }
@@ -299,73 +293,50 @@ void LogKlog::calculateCorrection(const log_time& monotonic,
299 } 293 }
300} 294}
301 295
302static const char suspendStr[] = "PM: suspend entry "; 296void LogKlog::sniffTime(log_time& now, const char*& buf, ssize_t len,
303static const char resumeStr[] = "PM: suspend exit ";
304static const char suspendedStr[] = "Suspended for ";
305
306const char* android::strnstr(const char* s, size_t len, const char* needle) {
307 char c;
308
309 if (!len) return NULL;
310 if ((c = *needle++) != 0) {
311 size_t needleLen = strlen(needle);
312 do {
313 do {
314 if (len <= needleLen) return NULL;
315 --len;
316 } while (*s++ != c);
317 } while (fastcmp<memcmp>(s, needle, needleLen));
318 s--;
319 }
320 return s;
321}
322
323void LogKlog::sniffTime(log_time& now, const char** buf, size_t len,
324 bool reverse) { 297 bool reverse) {
325 const char* cp = now.strptime(*buf, "[ %s.%q]"); 298 if (len <= 0) return;
326 if (cp && (cp >= &(*buf)[len])) { 299
327 cp = NULL; 300 const char* cp = nullptr;
301 if ((len > 10) && (*buf == '[')) {
302 cp = now.strptime(buf, "[ %s.%q]"); // can index beyond buffer bounds
303 if (cp && (cp > &buf[len - 1])) cp = nullptr;
328 } 304 }
329 if (cp) { 305 if (cp) {
330 static const char healthd[] = "healthd"; 306 len -= cp - buf;
331 static const char battery[] = ": battery "; 307 if ((len > 0) && isspace(*cp)) {
332
333 len -= cp - *buf;
334 if (len && isspace(*cp)) {
335 ++cp; 308 ++cp;
336 --len; 309 --len;
337 } 310 }
338 *buf = cp; 311 buf = cp;
339 312
340 if (isMonotonic()) { 313 if (isMonotonic()) return;
341 return;
342 }
343 314
344 const char* b; 315 const char* b;
345 if (((b = android::strnstr(cp, len, suspendStr))) && 316 if (((b = android::strnstr(cp, len, suspendStr))) &&
346 ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { 317 (((b += strlen(suspendStr)) - cp) < len)) {
347 len -= b - cp; 318 len -= b - cp;
348 calculateCorrection(now, b, len); 319 calculateCorrection(now, b, len);
349 } else if (((b = android::strnstr(cp, len, resumeStr))) && 320 } else if (((b = android::strnstr(cp, len, resumeStr))) &&
350 ((size_t)((b += sizeof(resumeStr) - 1) - cp) < len)) { 321 (((b += strlen(resumeStr)) - cp) < len)) {
351 len -= b - cp; 322 len -= b - cp;
352 calculateCorrection(now, b, len); 323 calculateCorrection(now, b, len);
353 } else if (((b = android::strnstr(cp, len, healthd))) && 324 } else if (((b = android::strnstr(cp, len, healthdStr))) &&
354 ((size_t)((b += sizeof(healthd) - 1) - cp) < len) && 325 (((b += strlen(healthdStr)) - cp) < len) &&
355 ((b = android::strnstr(b, len -= b - cp, battery))) && 326 ((b = android::strnstr(b, len -= b - cp, batteryStr))) &&
356 ((size_t)((b += sizeof(battery) - 1) - cp) < len)) { 327 (((b += strlen(batteryStr)) - cp) < len)) {
357 // NB: healthd is roughly 150us late, so we use it instead to 328 // NB: healthd is roughly 150us late, so we use it instead to
358 // trigger a check for ntp-induced or hardware clock drift. 329 // trigger a check for ntp-induced or hardware clock drift.
359 log_time real(CLOCK_REALTIME); 330 log_time real(CLOCK_REALTIME);
360 log_time mono(CLOCK_MONOTONIC); 331 log_time mono(CLOCK_MONOTONIC);
361 correction = (real < mono) ? log_time::EPOCH : (real - mono); 332 correction = (real < mono) ? log_time::EPOCH : (real - mono);
362 } else if (((b = android::strnstr(cp, len, suspendedStr))) && 333 } else if (((b = android::strnstr(cp, len, suspendedStr))) &&
363 ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { 334 (((b += strlen(suspendStr)) - cp) < len)) {
364 len -= b - cp; 335 len -= b - cp;
365 log_time real; 336 log_time real;
366 char* endp; 337 char* endp;
367 real.tv_sec = strtol(b, &endp, 10); 338 real.tv_sec = strtol(b, &endp, 10);
368 if ((*endp == '.') && ((size_t)(endp - b) < len)) { 339 if ((*endp == '.') && ((endp - b) < len)) {
369 unsigned long multiplier = NS_PER_SEC; 340 unsigned long multiplier = NS_PER_SEC;
370 real.tv_nsec = 0; 341 real.tv_nsec = 0;
371 len -= endp - b; 342 len -= endp - b;
@@ -394,8 +365,15 @@ void LogKlog::sniffTime(log_time& now, const char** buf, size_t len,
394 } 365 }
395} 366}
396 367
397pid_t LogKlog::sniffPid(const char** buf, size_t len) { 368pid_t LogKlog::sniffPid(const char*& buf, ssize_t len) {
398 const char* cp = *buf; 369 if (len <= 0) return 0;
370
371 const char* cp = buf;
372 // sscanf does a strlen, let's check if the string is not nul terminated.
373 // pseudo out-of-bounds access since we always have an extra char on buffer.
374 if (((ssize_t)strnlen(cp, len) == len) && cp[len]) {
375 return 0;
376 }
399 // HTC kernels with modified printk "c0 1648 " 377 // HTC kernels with modified printk "c0 1648 "
400 if ((len > 9) && (cp[0] == 'c') && isdigit(cp[1]) && 378 if ((len > 9) && (cp[0] == 'c') && isdigit(cp[1]) &&
401 (isdigit(cp[2]) || (cp[2] == ' ')) && (cp[3] == ' ')) { 379 (isdigit(cp[2]) || (cp[2] == ' ')) && (cp[3] == ' ')) {
@@ -412,7 +390,7 @@ pid_t LogKlog::sniffPid(const char** buf, size_t len) {
412 int pid = 0; 390 int pid = 0;
413 char dummy; 391 char dummy;
414 if (sscanf(cp + 4, "%d%c", &pid, &dummy) == 2) { 392 if (sscanf(cp + 4, "%d%c", &pid, &dummy) == 2) {
415 *buf = cp + 10; // skip-it-all 393 buf = cp + 10; // skip-it-all
416 return pid; 394 return pid;
417 } 395 }
418 } 396 }
@@ -434,28 +412,28 @@ pid_t LogKlog::sniffPid(const char** buf, size_t len) {
434} 412}
435 413
436// kernel log prefix, convert to a kernel log priority number 414// kernel log prefix, convert to a kernel log priority number
437static int parseKernelPrio(const char** buf, size_t len) { 415static int parseKernelPrio(const char*& buf, ssize_t len) {
438 int pri = LOG_USER | LOG_INFO; 416 int pri = LOG_USER | LOG_INFO;
439 const char* cp = *buf; 417 const char* cp = buf;
440 if (len && (*cp == '<')) { 418 if ((len > 0) && (*cp == '<')) {
441 pri = 0; 419 pri = 0;
442 while (--len && isdigit(*++cp)) { 420 while (--len && isdigit(*++cp)) {
443 pri = (pri * 10) + *cp - '0'; 421 pri = (pri * 10) + *cp - '0';
444 } 422 }
445 if (len && (*cp == '>')) { 423 if ((len > 0) && (*cp == '>')) {
446 ++cp; 424 ++cp;
447 } else { 425 } else {
448 cp = *buf; 426 cp = buf;
449 pri = LOG_USER | LOG_INFO; 427 pri = LOG_USER | LOG_INFO;
450 } 428 }
451 *buf = cp; 429 buf = cp;
452 } 430 }
453 return pri; 431 return pri;
454} 432}
455 433
456// Passed the entire SYSLOG_ACTION_READ_ALL buffer and interpret a 434// Passed the entire SYSLOG_ACTION_READ_ALL buffer and interpret a
457// compensated start time. 435// compensated start time.
458void LogKlog::synchronize(const char* buf, size_t len) { 436void LogKlog::synchronize(const char* buf, ssize_t len) {
459 const char* cp = android::strnstr(buf, len, suspendStr); 437 const char* cp = android::strnstr(buf, len, suspendStr);
460 if (!cp) { 438 if (!cp) {
461 cp = android::strnstr(buf, len, resumeStr); 439 cp = android::strnstr(buf, len, resumeStr);
@@ -471,10 +449,10 @@ void LogKlog::synchronize(const char* buf, size_t len) {
471 if (*cp == '\n') { 449 if (*cp == '\n') {
472 ++cp; 450 ++cp;
473 } 451 }
474 parseKernelPrio(&cp, len - (cp - buf)); 452 parseKernelPrio(cp, len - (cp - buf));
475 453
476 log_time now; 454 log_time now;
477 sniffTime(now, &cp, len - (cp - buf), true); 455 sniffTime(now, cp, len - (cp - buf), true);
478 456
479 const char* suspended = android::strnstr(buf, len, suspendedStr); 457 const char* suspended = android::strnstr(buf, len, suspendedStr);
480 if (!suspended || (suspended > cp)) { 458 if (!suspended || (suspended > cp)) {
@@ -488,9 +466,9 @@ void LogKlog::synchronize(const char* buf, size_t len) {
488 if (*cp == '\n') { 466 if (*cp == '\n') {
489 ++cp; 467 ++cp;
490 } 468 }
491 parseKernelPrio(&cp, len - (cp - buf)); 469 parseKernelPrio(cp, len - (cp - buf));
492 470
493 sniffTime(now, &cp, len - (cp - buf), true); 471 sniffTime(now, cp, len - (cp - buf), true);
494} 472}
495 473
496// Convert kernel log priority number into an Android Logger priority number 474// Convert kernel log priority number into an Android Logger priority number
@@ -523,9 +501,9 @@ static int convertKernelPrioToAndroidPrio(int pri) {
523 return ANDROID_LOG_INFO; 501 return ANDROID_LOG_INFO;
524} 502}
525 503
526static const char* strnrchr(const char* s, size_t len, char c) { 504static const char* strnrchr(const char* s, ssize_t len, char c) {
527 const char* save = NULL; 505 const char* save = nullptr;
528 for (; len; ++s, len--) { 506 for (; len > 0; ++s, len--) {
529 if (*s == c) { 507 if (*s == c) {
530 save = s; 508 save = s;
531 } 509 }
@@ -566,22 +544,21 @@ static const char* strnrchr(const char* s, size_t len, char c) {
566// logd.klogd: 544// logd.klogd:
567// return -1 if message logd.klogd: <signature> 545// return -1 if message logd.klogd: <signature>
568// 546//
569int LogKlog::log(const char* buf, size_t len) { 547int LogKlog::log(const char* buf, ssize_t len) {
570 if (auditd && android::strnstr(buf, len, " audit(")) { 548 if (auditd && android::strnstr(buf, len, auditStr)) {
571 return 0; 549 return 0;
572 } 550 }
573 551
574 const char* p = buf; 552 const char* p = buf;
575 int pri = parseKernelPrio(&p, len); 553 int pri = parseKernelPrio(p, len);
576 554
577 log_time now; 555 log_time now;
578 sniffTime(now, &p, len - (p - buf), false); 556 sniffTime(now, p, len - (p - buf), false);
579 557
580 // sniff for start marker 558 // sniff for start marker
581 const char klogd_message[] = "logd.klogd: "; 559 const char* start = android::strnstr(p, len - (p - buf), klogdStr);
582 const char* start = android::strnstr(p, len - (p - buf), klogd_message);
583 if (start) { 560 if (start) {
584 uint64_t sig = strtoll(start + sizeof(klogd_message) - 1, NULL, 10); 561 uint64_t sig = strtoll(start + strlen(klogdStr), nullptr, 10);
585 if (sig == signature.nsec()) { 562 if (sig == signature.nsec()) {
586 if (initialized) { 563 if (initialized) {
587 enableLogging = true; 564 enableLogging = true;
@@ -598,7 +575,7 @@ int LogKlog::log(const char* buf, size_t len) {
598 } 575 }
599 576
600 // Parse pid, tid and uid 577 // Parse pid, tid and uid
601 const pid_t pid = sniffPid(&p, len - (p - buf)); 578 const pid_t pid = sniffPid(p, len - (p - buf));
602 const pid_t tid = pid; 579 const pid_t tid = pid;
603 uid_t uid = AID_ROOT; 580 uid_t uid = AID_ROOT;
604 if (pid) { 581 if (pid) {
@@ -620,11 +597,11 @@ int LogKlog::log(const char* buf, size_t len) {
620 start = p; 597 start = p;
621 const char* tag = ""; 598 const char* tag = "";
622 const char* etag = tag; 599 const char* etag = tag;
623 size_t taglen = len - (p - buf); 600 ssize_t taglen = len - (p - buf);
624 const char* bt = p; 601 const char* bt = p;
625 602
626 static const char infoBrace[] = "[INFO]"; 603 static const char infoBrace[] = "[INFO]";
627 static const size_t infoBraceLen = strlen(infoBrace); 604 static const ssize_t infoBraceLen = strlen(infoBrace);
628 if ((taglen >= infoBraceLen) && 605 if ((taglen >= infoBraceLen) &&
629 !fastcmp<strncmp>(p, infoBrace, infoBraceLen)) { 606 !fastcmp<strncmp>(p, infoBrace, infoBraceLen)) {
630 // <PRI>[<TIME>] "[INFO]"<tag> ":" message 607 // <PRI>[<TIME>] "[INFO]"<tag> ":" message
@@ -633,26 +610,26 @@ int LogKlog::log(const char* buf, size_t len) {
633 } 610 }
634 611
635 const char* et; 612 const char* et;
636 for (et = bt; taglen && *et && (*et != ':') && !isspace(*et); 613 for (et = bt; (taglen > 0) && *et && (*et != ':') && !isspace(*et);
637 ++et, --taglen) { 614 ++et, --taglen) {
638 // skip ':' within [ ... ] 615 // skip ':' within [ ... ]
639 if (*et == '[') { 616 if (*et == '[') {
640 while (taglen && *et && *et != ']') { 617 while ((taglen > 0) && *et && *et != ']') {
641 ++et; 618 ++et;
642 --taglen; 619 --taglen;
643 } 620 }
644 if (!taglen) { 621 if (taglen <= 0) {
645 break; 622 break;
646 } 623 }
647 } 624 }
648 } 625 }
649 const char* cp; 626 const char* cp;
650 for (cp = et; taglen && isspace(*cp); ++cp, --taglen) { 627 for (cp = et; (taglen > 0) && isspace(*cp); ++cp, --taglen) {
651 } 628 }
652 629
653 // Validate tag 630 // Validate tag
654 size_t size = et - bt; 631 ssize_t size = et - bt;
655 if (taglen && size) { 632 if ((taglen > 0) && (size > 0)) {
656 if (*cp == ':') { 633 if (*cp == ':') {
657 // ToDo: handle case insensitive colon separated logging stutter: 634 // ToDo: handle case insensitive colon separated logging stutter:
658 // <tag> : <tag>: ... 635 // <tag> : <tag>: ...
@@ -672,12 +649,12 @@ int LogKlog::log(const char* buf, size_t len) {
672 const char* b = cp; 649 const char* b = cp;
673 cp += size; 650 cp += size;
674 taglen -= size; 651 taglen -= size;
675 while (--taglen && !isspace(*++cp) && (*cp != ':')) { 652 while ((--taglen > 0) && !isspace(*++cp) && (*cp != ':')) {
676 } 653 }
677 const char* e; 654 const char* e;
678 for (e = cp; taglen && isspace(*cp); ++cp, --taglen) { 655 for (e = cp; (taglen > 0) && isspace(*cp); ++cp, --taglen) {
679 } 656 }
680 if (taglen && (*cp == ':')) { 657 if ((taglen > 0) && (*cp == ':')) {
681 tag = b; 658 tag = b;
682 etag = e; 659 etag = e;
683 p = cp + 1; 660 p = cp + 1;
@@ -685,7 +662,7 @@ int LogKlog::log(const char* buf, size_t len) {
685 } else { 662 } else {
686 // what about <PRI>[<TIME>] <tag>_host '<tag><stuff>' : message 663 // what about <PRI>[<TIME>] <tag>_host '<tag><stuff>' : message
687 static const char host[] = "_host"; 664 static const char host[] = "_host";
688 static const size_t hostlen = strlen(host); 665 static const ssize_t hostlen = strlen(host);
689 if ((size > hostlen) && 666 if ((size > hostlen) &&
690 !fastcmp<strncmp>(bt + size - hostlen, host, hostlen) && 667 !fastcmp<strncmp>(bt + size - hostlen, host, hostlen) &&
691 !fastcmp<strncmp>(bt + 1, cp + 1, size - hostlen - 1)) { 668 !fastcmp<strncmp>(bt + 1, cp + 1, size - hostlen - 1)) {
@@ -693,12 +670,14 @@ int LogKlog::log(const char* buf, size_t len) {
693 cp += size - hostlen; 670 cp += size - hostlen;
694 taglen -= size - hostlen; 671 taglen -= size - hostlen;
695 if (*cp == '.') { 672 if (*cp == '.') {
696 while (--taglen && !isspace(*++cp) && (*cp != ':')) { 673 while ((--taglen > 0) && !isspace(*++cp) &&
674 (*cp != ':')) {
697 } 675 }
698 const char* e; 676 const char* e;
699 for (e = cp; taglen && isspace(*cp); ++cp, --taglen) { 677 for (e = cp; (taglen > 0) && isspace(*cp);
678 ++cp, --taglen) {
700 } 679 }
701 if (taglen && (*cp == ':')) { 680 if ((taglen > 0) && (*cp == ':')) {
702 tag = b; 681 tag = b;
703 etag = e; 682 etag = e;
704 p = cp + 1; 683 p = cp + 1;
@@ -711,13 +690,13 @@ int LogKlog::log(const char* buf, size_t len) {
711 } else { 690 } else {
712 // <PRI>[<TIME>] <tag> <stuff>' : message 691 // <PRI>[<TIME>] <tag> <stuff>' : message
713 twoWord: 692 twoWord:
714 while (--taglen && !isspace(*++cp) && (*cp != ':')) { 693 while ((--taglen > 0) && !isspace(*++cp) && (*cp != ':')) {
715 } 694 }
716 const char* e; 695 const char* e;
717 for (e = cp; taglen && isspace(*cp); ++cp, --taglen) { 696 for (e = cp; (taglen > 0) && isspace(*cp); ++cp, --taglen) {
718 } 697 }
719 // Two words 698 // Two words
720 if (taglen && (*cp == ':')) { 699 if ((taglen > 0) && (*cp == ':')) {
721 tag = bt; 700 tag = bt;
722 etag = e; 701 etag = e;
723 p = cp + 1; 702 p = cp + 1;
@@ -726,13 +705,13 @@ int LogKlog::log(const char* buf, size_t len) {
726 } // else no tag 705 } // else no tag
727 706
728 static const char cpu[] = "CPU"; 707 static const char cpu[] = "CPU";
729 static const size_t cpuLen = strlen(cpu); 708 static const ssize_t cpuLen = strlen(cpu);
730 static const char warning[] = "WARNING"; 709 static const char warning[] = "WARNING";
731 static const size_t warningLen = strlen(warning); 710 static const ssize_t warningLen = strlen(warning);
732 static const char error[] = "ERROR"; 711 static const char error[] = "ERROR";
733 static const size_t errorLen = strlen(error); 712 static const ssize_t errorLen = strlen(error);
734 static const char info[] = "INFO"; 713 static const char info[] = "INFO";
735 static const size_t infoLen = strlen(info); 714 static const ssize_t infoLen = strlen(info);
736 715
737 size = etag - tag; 716 size = etag - tag;
738 if ((size <= 1) || 717 if ((size <= 1) ||
@@ -756,13 +735,13 @@ int LogKlog::log(const char* buf, size_t len) {
756 // Mediatek-special printk induced stutter 735 // Mediatek-special printk induced stutter
757 const char* mp = strnrchr(tag, taglen, ']'); 736 const char* mp = strnrchr(tag, taglen, ']');
758 if (mp && (++mp < etag)) { 737 if (mp && (++mp < etag)) {
759 size_t s = etag - mp; 738 ssize_t s = etag - mp;
760 if (((s + s) < taglen) && !fastcmp<memcmp>(mp, mp - 1 - s, s)) { 739 if (((s + s) < taglen) && !fastcmp<memcmp>(mp, mp - 1 - s, s)) {
761 taglen = mp - tag; 740 taglen = mp - tag;
762 } 741 }
763 } 742 }
764 // Deal with sloppy and simplistic harmless p = cp + 1 etc above. 743 // Deal with sloppy and simplistic harmless p = cp + 1 etc above.
765 if (len < (size_t)(p - buf)) { 744 if (len < (p - buf)) {
766 p = &buf[len]; 745 p = &buf[len];
767 } 746 }
768 // skip leading space 747 // skip leading space
@@ -770,12 +749,12 @@ int LogKlog::log(const char* buf, size_t len) {
770 ++p; 749 ++p;
771 } 750 }
772 // truncate trailing space or nuls 751 // truncate trailing space or nuls
773 size_t b = len - (p - buf); 752 ssize_t b = len - (p - buf);
774 while (b && (isspace(p[b - 1]) || !p[b - 1])) { 753 while ((b > 0) && (isspace(p[b - 1]) || !p[b - 1])) {
775 --b; 754 --b;
776 } 755 }
777 // trick ... allow tag with empty content to be logged. log() drops empty 756 // trick ... allow tag with empty content to be logged. log() drops empty
778 if (!b && taglen) { 757 if ((b <= 0) && (taglen > 0)) {
779 p = " "; 758 p = " ";
780 b = 1; 759 b = 1;
781 } 760 }
@@ -787,9 +766,9 @@ int LogKlog::log(const char* buf, size_t len) {
787 taglen = LOGGER_ENTRY_MAX_PAYLOAD; 766 taglen = LOGGER_ENTRY_MAX_PAYLOAD;
788 } 767 }
789 // calculate buffer copy requirements 768 // calculate buffer copy requirements
790 size_t n = 1 + taglen + 1 + b + 1; 769 ssize_t n = 1 + taglen + 1 + b + 1;
791 // paranoid sanity check, first two just can not happen ... 770 // paranoid sanity check, first two just can not happen ...
792 if ((taglen > n) || (b > n) || (n > USHRT_MAX)) { 771 if ((taglen > n) || (b > n) || (n > (ssize_t)USHRT_MAX) || (n <= 0)) {
793 return -EINVAL; 772 return -EINVAL;
794 } 773 }
795 774