1 /* 2 * Copyright (C) 2012-2013 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 <dirent.h> 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <poll.h> 21 #include <sched.h> 22 #include <semaphore.h> 23 #include <signal.h> 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <sys/capability.h> 28 #include <sys/klog.h> 29 #include <sys/prctl.h> 30 #include <sys/resource.h> 31 #include <sys/stat.h> 32 #include <sys/types.h> 33 #include <syslog.h> 34 #include <unistd.h> 35 36 #include <cstdbool> 37 #include <memory> 38 39 #include <android-base/macros.h> 40 #include <cutils/android_get_control_file.h> 41 #include <cutils/properties.h> 42 #include <cutils/sched_policy.h> 43 #include <cutils/sockets.h> 44 #include <log/event_tag_map.h> 45 #include <packagelistparser/packagelistparser.h> 46 #include <private/android_filesystem_config.h> 47 #include <private/android_logger.h> 48 #include <utils/threads.h> 49 50 #include "CommandListener.h" 51 #include "LogAudit.h" 52 #include "LogBuffer.h" 53 #include "LogKlog.h" 54 #include "LogListener.h" 55 #include "LogUtils.h" 56 57 #define KMSG_PRIORITY(PRI) \ 58 '<', '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) / 10, \ 59 '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) % 10, '>' 60 61 // 62 // The service is designed to be run by init, it does not respond well 63 // to starting up manually. When starting up manually the sockets will 64 // fail to open typically for one of the following reasons: 65 // EADDRINUSE if logger is running. 66 // EACCESS if started without precautions (below) 67 // 68 // Here is a cookbook procedure for starting up logd manually assuming 69 // init is out of the way, pedantically all permissions and SELinux 70 // security is put back in place: 71 // 72 // setenforce 0 73 // rm /dev/socket/logd* 74 // chmod 777 /dev/socket 75 // # here is where you would attach the debugger or valgrind for example 76 // runcon u:r:logd:s0 /system/bin/logd </dev/null >/dev/null 2>&1 & 77 // sleep 1 78 // chmod 755 /dev/socket 79 // chown logd.logd /dev/socket/logd* 80 // restorecon /dev/socket/logd* 81 // setenforce 1 82 // 83 // If minimalism prevails, typical for debugging and security is not a concern: 84 // 85 // setenforce 0 86 // chmod 777 /dev/socket 87 // logd 88 // 89 90 static int drop_privs(bool klogd, bool auditd) { 91 // Tricky, if ro.build.type is "eng" then this is true because of the 92 // side effect that ro.debuggable == 1 as well, else it is false. 93 bool eng = 94 __android_logger_property_get_bool("ro.build.type", BOOL_DEFAULT_FALSE); 95 96 struct sched_param param; 97 memset(¶m, 0, sizeof(param)); 98 99 if (set_sched_policy(0, SP_BACKGROUND) < 0) { 100 android::prdebug("failed to set background scheduling policy"); 101 if (!eng) return -1; 102 } 103 104 if (sched_setscheduler((pid_t)0, SCHED_BATCH, ¶m) < 0) { 105 android::prdebug("failed to set batch scheduler"); 106 if (!eng) return -1; 107 } 108 109 if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { 110 android::prdebug("failed to set background cgroup"); 111 if (!eng) return -1; 112 } 113 114 if (!eng && (prctl(PR_SET_DUMPABLE, 0) < 0)) { 115 android::prdebug("failed to clear PR_SET_DUMPABLE"); 116 return -1; 117 } 118 119 if (prctl(PR_SET_KEEPCAPS, 1) < 0) { 120 android::prdebug("failed to set PR_SET_KEEPCAPS"); 121 if (!eng) return -1; 122 } 123 124 std::unique_ptr<struct _cap_struct, int (*)(void*)> caps(cap_init(), 125 cap_free); 126 if (cap_clear(caps.get()) < 0) return -1; 127 cap_value_t cap_value[] = { CAP_SETGID, // must be first for below 128 klogd ? CAP_SYSLOG : CAP_SETGID, 129 auditd ? CAP_AUDIT_CONTROL : CAP_SETGID }; 130 if (cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(cap_value), cap_value, 131 CAP_SET) < 0) { 132 return -1; 133 } 134 if (cap_set_flag(caps.get(), CAP_EFFECTIVE, arraysize(cap_value), cap_value, 135 CAP_SET) < 0) { 136 return -1; 137 } 138 if (cap_set_proc(caps.get()) < 0) { 139 android::prdebug( 140 "failed to set CAP_SETGID, CAP_SYSLOG or CAP_AUDIT_CONTROL (%d)", 141 errno); 142 if (!eng) return -1; 143 } 144 145 gid_t groups[] = { AID_READPROC }; 146 147 if (setgroups(arraysize(groups), groups) == -1) { 148 android::prdebug("failed to set AID_READPROC groups"); 149 if (!eng) return -1; 150 } 151 152 if (setgid(AID_LOGD) != 0) { 153 android::prdebug("failed to set AID_LOGD gid"); 154 if (!eng) return -1; 155 } 156 157 if (setuid(AID_LOGD) != 0) { 158 android::prdebug("failed to set AID_LOGD uid"); 159 if (!eng) return -1; 160 } 161 162 if (cap_set_flag(caps.get(), CAP_PERMITTED, 1, cap_value, CAP_CLEAR) < 0) { 163 return -1; 164 } 165 if (cap_set_flag(caps.get(), CAP_EFFECTIVE, 1, cap_value, CAP_CLEAR) < 0) { 166 return -1; 167 } 168 if (cap_set_proc(caps.get()) < 0) { 169 android::prdebug("failed to clear CAP_SETGID (%d)", errno); 170 if (!eng) return -1; 171 } 172 173 return 0; 174 } 175 176 // Property helper 177 static bool check_flag(const char* prop, const char* flag) { 178 const char* cp = strcasestr(prop, flag); 179 if (!cp) { 180 return false; 181 } 182 // We only will document comma (,) 183 static const char sep[] = ",:;|+ \t\f"; 184 if ((cp != prop) && !strchr(sep, cp[-1])) { 185 return false; 186 } 187 cp += strlen(flag); 188 return !*cp || !!strchr(sep, *cp); 189 } 190 191 static int fdDmesg = -1; 192 void android::prdebug(const char* fmt, ...) { 193 if (fdDmesg < 0) { 194 return; 195 } 196 197 static const char message[] = { 198 KMSG_PRIORITY(LOG_DEBUG), 'l', 'o', 'g', 'd', ':', ' ' 199 }; 200 char buffer[256]; 201 memcpy(buffer, message, sizeof(message)); 202 203 va_list ap; 204 va_start(ap, fmt); 205 int n = vsnprintf(buffer + sizeof(message), 206 sizeof(buffer) - sizeof(message), fmt, ap); 207 va_end(ap); 208 if (n > 0) { 209 buffer[sizeof(buffer) - 1] = '\0'; 210 if (!strchr(buffer, '\n')) { 211 buffer[sizeof(buffer) - 2] = '\0'; 212 strlcat(buffer, "\n", sizeof(buffer)); 213 } 214 write(fdDmesg, buffer, strlen(buffer)); 215 } 216 } 217 218 static sem_t uidName; 219 static uid_t uid; 220 static char* name; 221 222 static sem_t reinit; 223 static bool reinit_running = false; 224 static LogBuffer* logBuf = nullptr; 225 226 static bool package_list_parser_cb(pkg_info* info, void* /* userdata */) { 227 bool rc = true; 228 if (info->uid == uid) { 229 name = strdup(info->name); 230 // false to stop processing 231 rc = false; 232 } 233 234 packagelist_free(info); 235 return rc; 236 } 237 238 static void* reinit_thread_start(void* /*obj*/) { 239 prctl(PR_SET_NAME, "logd.daemon"); 240 set_sched_policy(0, SP_BACKGROUND); 241 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND); 242 243 cap_t caps = cap_init(); 244 (void)cap_clear(caps); 245 (void)cap_set_proc(caps); 246 (void)cap_free(caps); 247 248 // If we are AID_ROOT, we should drop to AID_LOGD+AID_SYSTEM, if we are 249 // anything else, we have even lesser privileges and accept our fate. Not 250 // worth checking for error returns setting this thread's privileges. 251 (void)setgid(AID_SYSTEM); // readonly access to /data/system/packages.list 252 (void)setuid(AID_LOGD); // access to everything logd, eg /data/misc/logd 253 254 while (reinit_running && !sem_wait(&reinit) && reinit_running) { 255 // uidToName Privileged Worker 256 if (uid) { 257 name = nullptr; 258 259 packagelist_parse(package_list_parser_cb, nullptr); 260 261 uid = 0; 262 sem_post(&uidName); 263 continue; 264 } 265 266 if (fdDmesg >= 0) { 267 static const char reinit_message[] = { KMSG_PRIORITY(LOG_INFO), 268 'l', 269 'o', 270 'g', 271 'd', 272 '.', 273 'd', 274 'a', 275 'e', 276 'm', 277 'o', 278 'n', 279 ':', 280 ' ', 281 'r', 282 'e', 283 'i', 284 'n', 285 'i', 286 't', 287 '\n' }; 288 write(fdDmesg, reinit_message, sizeof(reinit_message)); 289 } 290 291 // Anything that reads persist.<property> 292 if (logBuf) { 293 logBuf->init(); 294 logBuf->initPrune(nullptr); 295 } 296 android::ReReadEventLogTags(); 297 } 298 299 return nullptr; 300 } 301 302 static sem_t sem_name; 303 304 char* android::uidToName(uid_t u) { 305 if (!u || !reinit_running) { 306 return nullptr; 307 } 308 309 sem_wait(&sem_name); 310 311 // Not multi-thread safe, we use sem_name to protect 312 uid = u; 313 314 name = nullptr; 315 sem_post(&reinit); 316 sem_wait(&uidName); 317 char* ret = name; 318 319 sem_post(&sem_name); 320 321 return ret; 322 } 323 324 // Serves as a global method to trigger reinitialization 325 // and as a function that can be provided to signal(). 326 void reinit_signal_handler(int /*signal*/) { 327 sem_post(&reinit); 328 } 329 330 static void readDmesg(LogAudit* al, LogKlog* kl) { 331 if (!al && !kl) { 332 return; 333 } 334 335 int rc = klogctl(KLOG_SIZE_BUFFER, nullptr, 0); 336 if (rc <= 0) { 337 return; 338 } 339 340 // Margin for additional input race or trailing nul 341 ssize_t len = rc + 1024; 342 std::unique_ptr<char[]> buf(new char[len]); 343 344 rc = klogctl(KLOG_READ_ALL, buf.get(), len); 345 if (rc <= 0) { 346 return; 347 } 348 349 if (rc < len) { 350 len = rc + 1; 351 } 352 buf[--len] = '\0'; 353 354 if (kl && kl->isMonotonic()) { 355 kl->synchronize(buf.get(), len); 356 } 357 358 ssize_t sublen; 359 for (char *ptr = nullptr, *tok = buf.get(); 360 (rc >= 0) && !!(tok = android::log_strntok_r(tok, len, ptr, sublen)); 361 tok = nullptr) { 362 if ((sublen <= 0) || !*tok) continue; 363 if (al) { 364 rc = al->log(tok, sublen); 365 } 366 if (kl) { 367 rc = kl->log(tok, sublen); 368 } 369 } 370 } 371 372 static int issueReinit() { 373 cap_t caps = cap_init(); 374 (void)cap_clear(caps); 375 (void)cap_set_proc(caps); 376 (void)cap_free(caps); 377 378 int sock = TEMP_FAILURE_RETRY(socket_local_client( 379 "logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM)); 380 if (sock < 0) return -errno; 381 382 static const char reinitStr[] = "reinit"; 383 ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinitStr, sizeof(reinitStr))); 384 if (ret < 0) return -errno; 385 386 struct pollfd p; 387 memset(&p, 0, sizeof(p)); 388 p.fd = sock; 389 p.events = POLLIN; 390 ret = TEMP_FAILURE_RETRY(poll(&p, 1, 1000)); 391 if (ret < 0) return -errno; 392 if ((ret == 0) || !(p.revents & POLLIN)) return -ETIME; 393 394 static const char success[] = "success"; 395 char buffer[sizeof(success) - 1]; 396 memset(buffer, 0, sizeof(buffer)); 397 ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); 398 if (ret < 0) return -errno; 399 400 return strncmp(buffer, success, sizeof(success) - 1) != 0; 401 } 402 403 // Foreground waits for exit of the main persistent threads 404 // that are started here. The threads are created to manage 405 // UNIX domain client sockets for writing, reading and 406 // controlling the user space logger, and for any additional 407 // logging plugins like auditd and restart control. Additional 408 // transitory per-client threads are created for each reader. 409 int main(int argc, char* argv[]) { 410 // issue reinit command. KISS argument parsing. 411 if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { 412 return issueReinit(); 413 } 414 415 static const char dev_kmsg[] = "/dev/kmsg"; 416 fdDmesg = android_get_control_file(dev_kmsg); 417 if (fdDmesg < 0) { 418 fdDmesg = TEMP_FAILURE_RETRY(open(dev_kmsg, O_WRONLY | O_CLOEXEC)); 419 } 420 421 int fdPmesg = -1; 422 bool klogd = __android_logger_property_get_bool( 423 "logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | 424 BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE); 425 if (klogd) { 426 static const char proc_kmsg[] = "/proc/kmsg"; 427 fdPmesg = android_get_control_file(proc_kmsg); 428 if (fdPmesg < 0) { 429 fdPmesg = TEMP_FAILURE_RETRY( 430 open(proc_kmsg, O_RDONLY | O_NDELAY | O_CLOEXEC)); 431 } 432 if (fdPmesg < 0) android::prdebug("Failed to open %s\n", proc_kmsg); 433 } 434 435 // Reinit Thread 436 sem_init(&reinit, 0, 0); 437 sem_init(&uidName, 0, 0); 438 sem_init(&sem_name, 0, 1); 439 pthread_attr_t attr; 440 if (!pthread_attr_init(&attr)) { 441 struct sched_param param; 442 443 memset(¶m, 0, sizeof(param)); 444 pthread_attr_setschedparam(&attr, ¶m); 445 pthread_attr_setschedpolicy(&attr, SCHED_BATCH); 446 if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { 447 pthread_t thread; 448 reinit_running = true; 449 if (pthread_create(&thread, &attr, reinit_thread_start, nullptr)) { 450 reinit_running = false; 451 } 452 } 453 pthread_attr_destroy(&attr); 454 } 455 456 bool auditd = 457 __android_logger_property_get_bool("ro.logd.auditd", BOOL_DEFAULT_TRUE); 458 if (drop_privs(klogd, auditd) != 0) { 459 return -1; 460 } 461 462 // Serves the purpose of managing the last logs times read on a 463 // socket connection, and as a reader lock on a range of log 464 // entries. 465 466 LastLogTimes* times = new LastLogTimes(); 467 468 // LogBuffer is the object which is responsible for holding all 469 // log entries. 470 471 logBuf = new LogBuffer(times); 472 473 signal(SIGHUP, reinit_signal_handler); 474 475 if (__android_logger_property_get_bool( 476 "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | 477 BOOL_DEFAULT_FLAG_ENG | 478 BOOL_DEFAULT_FLAG_SVELTE)) { 479 logBuf->enableStatistics(); 480 } 481 482 // LogReader listens on /dev/socket/logdr. When a client 483 // connects, log entries in the LogBuffer are written to the client. 484 485 LogReader* reader = new LogReader(logBuf); 486 if (reader->startListener()) { 487 exit(1); 488 } 489 490 // LogListener listens on /dev/socket/logdw for client 491 // initiated log messages. New log entries are added to LogBuffer 492 // and LogReader is notified to send updates to connected clients. 493 494 LogListener* swl = new LogListener(logBuf, reader); 495 // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value 496 if (swl->startListener(600)) { 497 exit(1); 498 } 499 500 // Command listener listens on /dev/socket/logd for incoming logd 501 // administrative commands. 502 503 CommandListener* cl = new CommandListener(logBuf, reader, swl); 504 if (cl->startListener()) { 505 exit(1); 506 } 507 508 // LogAudit listens on NETLINK_AUDIT socket for selinux 509 // initiated log messages. New log entries are added to LogBuffer 510 // and LogReader is notified to send updates to connected clients. 511 512 LogAudit* al = nullptr; 513 if (auditd) { 514 al = new LogAudit(logBuf, reader, 515 __android_logger_property_get_bool( 516 "ro.logd.auditd.dmesg", BOOL_DEFAULT_TRUE) 517 ? fdDmesg 518 : -1); 519 } 520 521 LogKlog* kl = nullptr; 522 if (klogd) { 523 kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != nullptr); 524 } 525 526 readDmesg(al, kl); 527 528 // failure is an option ... messages are in dmesg (required by standard) 529 530 if (kl && kl->startListener()) { 531 delete kl; 532 } 533 534 if (al && al->startListener()) { 535 delete al; 536 } 537 538 TEMP_FAILURE_RETRY(pause()); 539 540 exit(0); 541 } 542