10175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn/* 20175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Copyright (C) 2012-2013 The Android Open Source Project 30175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * 40175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License"); 50175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * you may not use this file except in compliance with the License. 60175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * You may obtain a copy of the License at 70175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * 80175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * http://www.apache.org/licenses/LICENSE-2.0 90175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * 100175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Unless required by applicable law or agreed to in writing, software 110175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS, 120175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * See the License for the specific language governing permissions and 140175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * limitations under the License. 150175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn */ 160175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 170175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <dirent.h> 180175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <errno.h> 190175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <fcntl.h> 2011e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn#include <poll.h> 21882f856668331488d9bbaec429de7aac5d7978c9Mark Salyzyn#include <sched.h> 2211e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn#include <semaphore.h> 2311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn#include <signal.h> 240175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <stdio.h> 250175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <stdlib.h> 260175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <string.h> 270175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <sys/capability.h> 28eb06de716b4f33e9fdb1c41f0cce61084545bfd5Mark Salyzyn#include <sys/klog.h> 29e5a0f2064bcecbea2b0b1afd72033508e96c5c64Elliott Hughes#include <sys/prctl.h> 30d98f4e8af5076e6a9dbd4ddc2c375cb7bcda8cd8Riley Andrews#include <sys/resource.h> 310175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <sys/stat.h> 320175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <sys/types.h> 33ccbadc6be015553357a4c50de48dea46cb1adcbaMark Salyzyn#include <syslog.h> 34e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn#include <unistd.h> 350175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 36aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts#include <cstdbool> 37d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn#include <memory> 38d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn 392bbdbe85410d3d076e5984ea9a5fa6f2cbbda6e2Jorge Lucangeli Obes#include <android-base/macros.h> 4052bd37e63373b410c009e8611508191dfbf31d30Mark Salyzyn#include <cutils/android_get_control_file.h> 41e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn#include <cutils/properties.h> 4256ba4b5b77879f43541cd47c59176acea2d8dcc6Mark Salyzyn#include <cutils/sched_policy.h> 4311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn#include <cutils/sockets.h> 44ff32f3c77439b9791e58c225a8b7ca82dfc2c3daMark Salyzyn#include <log/event_tag_map.h> 45aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts#include <packagelistparser/packagelistparser.h> 46e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn#include <private/android_filesystem_config.h> 475740a46e4ea87100acf6a83319d8b94c5c602352Mark Salyzyn#include <private/android_logger.h> 48d98f4e8af5076e6a9dbd4ddc2c375cb7bcda8cd8Riley Andrews#include <utils/threads.h> 49e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn 500175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include "CommandListener.h" 5129d238d2a8e12c131a4cfbccb912e525cca6b10dWilliam Roberts#include "LogAudit.h" 52501c373916e292764400dbae735f44b33378400fMark Salyzyn#include "LogBuffer.h" 53a1aacb71f387c91d5fe383b8aaa5b0be2ec9cd3cMark Salyzyn#include "LogKlog.h" 54501c373916e292764400dbae735f44b33378400fMark Salyzyn#include "LogListener.h" 555ac5c6b19364b5b3061a59db796b2357c95c3b64Mark Salyzyn#include "LogUtils.h" 560175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 57501c373916e292764400dbae735f44b33378400fMark Salyzyn#define KMSG_PRIORITY(PRI) \ 58501c373916e292764400dbae735f44b33378400fMark Salyzyn '<', '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) / 10, \ 59501c373916e292764400dbae735f44b33378400fMark Salyzyn '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) % 10, '>' 60ccbadc6be015553357a4c50de48dea46cb1adcbaMark Salyzyn 61dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// 622bbdbe85410d3d076e5984ea9a5fa6f2cbbda6e2Jorge Lucangeli Obes// The service is designed to be run by init, it does not respond well 63dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// to starting up manually. When starting up manually the sockets will 64dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// fail to open typically for one of the following reasons: 65dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// EADDRINUSE if logger is running. 66dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// EACCESS if started without precautions (below) 67dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// 68dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// Here is a cookbook procedure for starting up logd manually assuming 692bbdbe85410d3d076e5984ea9a5fa6f2cbbda6e2Jorge Lucangeli Obes// init is out of the way, pedantically all permissions and SELinux 70dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// security is put back in place: 71dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// 72dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// setenforce 0 73dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// rm /dev/socket/logd* 74dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// chmod 777 /dev/socket 75dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// # here is where you would attach the debugger or valgrind for example 76dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// runcon u:r:logd:s0 /system/bin/logd </dev/null >/dev/null 2>&1 & 77dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// sleep 1 78dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// chmod 755 /dev/socket 79dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// chown logd.logd /dev/socket/logd* 80dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// restorecon /dev/socket/logd* 81dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// setenforce 1 82dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// 83dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// If minimalism prevails, typical for debugging and security is not a concern: 84dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// 85dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// setenforce 0 86dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// chmod 777 /dev/socket 87dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// logd 88dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn// 89dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn 90d2b3291ffa1cd9c2214b4a68d72508461de57e48Mark Salyzynstatic int drop_privs(bool klogd, bool auditd) { 91107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn // Tricky, if ro.build.type is "eng" then this is true because of the 92107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn // side effect that ro.debuggable == 1 as well, else it is false. 93501c373916e292764400dbae735f44b33378400fMark Salyzyn bool eng = 94501c373916e292764400dbae735f44b33378400fMark Salyzyn __android_logger_property_get_bool("ro.build.type", BOOL_DEFAULT_FALSE); 95107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn 96882f856668331488d9bbaec429de7aac5d7978c9Mark Salyzyn struct sched_param param; 97882f856668331488d9bbaec429de7aac5d7978c9Mark Salyzyn memset(¶m, 0, sizeof(param)); 98882f856668331488d9bbaec429de7aac5d7978c9Mark Salyzyn 9956ba4b5b77879f43541cd47c59176acea2d8dcc6Mark Salyzyn if (set_sched_policy(0, SP_BACKGROUND) < 0) { 100107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn android::prdebug("failed to set background scheduling policy"); 101107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng) return -1; 10256ba4b5b77879f43541cd47c59176acea2d8dcc6Mark Salyzyn } 10356ba4b5b77879f43541cd47c59176acea2d8dcc6Mark Salyzyn 104501c373916e292764400dbae735f44b33378400fMark Salyzyn if (sched_setscheduler((pid_t)0, SCHED_BATCH, ¶m) < 0) { 105107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn android::prdebug("failed to set batch scheduler"); 106107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng) return -1; 107882f856668331488d9bbaec429de7aac5d7978c9Mark Salyzyn } 108882f856668331488d9bbaec429de7aac5d7978c9Mark Salyzyn 109d98f4e8af5076e6a9dbd4ddc2c375cb7bcda8cd8Riley Andrews if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { 110107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn android::prdebug("failed to set background cgroup"); 111107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng) return -1; 112d98f4e8af5076e6a9dbd4ddc2c375cb7bcda8cd8Riley Andrews } 113d98f4e8af5076e6a9dbd4ddc2c375cb7bcda8cd8Riley Andrews 114107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng && (prctl(PR_SET_DUMPABLE, 0) < 0)) { 1156a70ded7bfa8914aaa3dc25630ff2713ae893f80Mark Salyzyn android::prdebug("failed to clear PR_SET_DUMPABLE"); 1166a70ded7bfa8914aaa3dc25630ff2713ae893f80Mark Salyzyn return -1; 1176a70ded7bfa8914aaa3dc25630ff2713ae893f80Mark Salyzyn } 1186a70ded7bfa8914aaa3dc25630ff2713ae893f80Mark Salyzyn 119f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn if (prctl(PR_SET_KEEPCAPS, 1) < 0) { 120f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn android::prdebug("failed to set PR_SET_KEEPCAPS"); 121107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng) return -1; 122f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn } 123f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn 124501c373916e292764400dbae735f44b33378400fMark Salyzyn std::unique_ptr<struct _cap_struct, int (*)(void*)> caps(cap_init(), 125501c373916e292764400dbae735f44b33378400fMark Salyzyn cap_free); 126f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn if (cap_clear(caps.get()) < 0) return -1; 127501c373916e292764400dbae735f44b33378400fMark Salyzyn cap_value_t cap_value[] = { CAP_SETGID, // must be first for below 128501c373916e292764400dbae735f44b33378400fMark Salyzyn klogd ? CAP_SYSLOG : CAP_SETGID, 129501c373916e292764400dbae735f44b33378400fMark Salyzyn auditd ? CAP_AUDIT_CONTROL : CAP_SETGID }; 130501c373916e292764400dbae735f44b33378400fMark Salyzyn if (cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(cap_value), cap_value, 131501c373916e292764400dbae735f44b33378400fMark Salyzyn CAP_SET) < 0) { 132501c373916e292764400dbae735f44b33378400fMark Salyzyn return -1; 133501c373916e292764400dbae735f44b33378400fMark Salyzyn } 134501c373916e292764400dbae735f44b33378400fMark Salyzyn if (cap_set_flag(caps.get(), CAP_EFFECTIVE, arraysize(cap_value), cap_value, 135501c373916e292764400dbae735f44b33378400fMark Salyzyn CAP_SET) < 0) { 136501c373916e292764400dbae735f44b33378400fMark Salyzyn return -1; 137501c373916e292764400dbae735f44b33378400fMark Salyzyn } 138f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn if (cap_set_proc(caps.get()) < 0) { 139501c373916e292764400dbae735f44b33378400fMark Salyzyn android::prdebug( 140501c373916e292764400dbae735f44b33378400fMark Salyzyn "failed to set CAP_SETGID, CAP_SYSLOG or CAP_AUDIT_CONTROL (%d)", 141501c373916e292764400dbae735f44b33378400fMark Salyzyn errno); 142107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng) return -1; 143f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn } 144f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn 145c39ba5ae32afb6329d42e61d2941d87ff66d92e3Nick Kralevich gid_t groups[] = { AID_READPROC }; 146f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn 147f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn if (setgroups(arraysize(groups), groups) == -1) { 148f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn android::prdebug("failed to set AID_READPROC groups"); 149107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng) return -1; 150f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn } 151f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn 152f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn if (setgid(AID_LOGD) != 0) { 153f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn android::prdebug("failed to set AID_LOGD gid"); 154107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng) return -1; 155f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn } 156f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn 157f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn if (setuid(AID_LOGD) != 0) { 158f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn android::prdebug("failed to set AID_LOGD uid"); 159107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng) return -1; 160f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn } 161f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn 162501c373916e292764400dbae735f44b33378400fMark Salyzyn if (cap_set_flag(caps.get(), CAP_PERMITTED, 1, cap_value, CAP_CLEAR) < 0) { 163501c373916e292764400dbae735f44b33378400fMark Salyzyn return -1; 164501c373916e292764400dbae735f44b33378400fMark Salyzyn } 165501c373916e292764400dbae735f44b33378400fMark Salyzyn if (cap_set_flag(caps.get(), CAP_EFFECTIVE, 1, cap_value, CAP_CLEAR) < 0) { 166501c373916e292764400dbae735f44b33378400fMark Salyzyn return -1; 167501c373916e292764400dbae735f44b33378400fMark Salyzyn } 168f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn if (cap_set_proc(caps.get()) < 0) { 169f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn android::prdebug("failed to clear CAP_SETGID (%d)", errno); 170107e29ac1b1c297a0d4ee35c4978e79f47013e2cMark Salyzyn if (!eng) return -1; 171f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn } 172f0b8e1bce61e839d5f94fb0918423b0eda14c779Mark Salyzyn 1730175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return 0; 1740175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn} 1750175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 176e0fa291e898b451dc198ed52cebac3ffefac066eMark Salyzyn// Property helper 177501c373916e292764400dbae735f44b33378400fMark Salyzynstatic bool check_flag(const char* prop, const char* flag) { 178501c373916e292764400dbae735f44b33378400fMark Salyzyn const char* cp = strcasestr(prop, flag); 1799c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn if (!cp) { 1809c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn return false; 1819c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn } 1829c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn // We only will document comma (,) 1839c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn static const char sep[] = ",:;|+ \t\f"; 1849c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn if ((cp != prop) && !strchr(sep, cp[-1])) { 1859c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn return false; 1869c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn } 1879c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn cp += strlen(flag); 1889c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn return !*cp || !!strchr(sep, *cp); 1899c66a58f216e88e46f4ceacbd54599c28a20a729Mark Salyzyn} 190e0fa291e898b451dc198ed52cebac3ffefac066eMark Salyzyn 191ccbadc6be015553357a4c50de48dea46cb1adcbaMark Salyzynstatic int fdDmesg = -1; 192501c373916e292764400dbae735f44b33378400fMark Salyzynvoid android::prdebug(const char* fmt, ...) { 193d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn if (fdDmesg < 0) { 194d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn return; 195d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn } 196d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn 197d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn static const char message[] = { 198d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn KMSG_PRIORITY(LOG_DEBUG), 'l', 'o', 'g', 'd', ':', ' ' 199d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn }; 200d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn char buffer[256]; 201d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn memcpy(buffer, message, sizeof(message)); 202d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn 203d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn va_list ap; 204d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn va_start(ap, fmt); 205d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn int n = vsnprintf(buffer + sizeof(message), 206d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn sizeof(buffer) - sizeof(message), fmt, ap); 207d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn va_end(ap); 208d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn if (n > 0) { 209d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn buffer[sizeof(buffer) - 1] = '\0'; 210d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn if (!strchr(buffer, '\n')) { 211d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn buffer[sizeof(buffer) - 2] = '\0'; 212d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn strlcat(buffer, "\n", sizeof(buffer)); 213d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn } 214d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn write(fdDmesg, buffer, strlen(buffer)); 215d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn } 216d048f113a3fa0797cde2887632bcca4bb82b111eMark Salyzyn} 217ccbadc6be015553357a4c50de48dea46cb1adcbaMark Salyzyn 21808739ba71fc1f2659149be760405d622e5b68f06Mark Salyzynstatic sem_t uidName; 21908739ba71fc1f2659149be760405d622e5b68f06Mark Salyzynstatic uid_t uid; 220501c373916e292764400dbae735f44b33378400fMark Salyzynstatic char* name; 22108739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn 22211e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzynstatic sem_t reinit; 22311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzynstatic bool reinit_running = false; 2240484b3b5757594a43c6b646824b44643d2a007deMark Salyzynstatic LogBuffer* logBuf = nullptr; 225aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts 226501c373916e292764400dbae735f44b33378400fMark Salyzynstatic bool package_list_parser_cb(pkg_info* info, void* /* userdata */) { 227aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts bool rc = true; 228aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts if (info->uid == uid) { 229aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts name = strdup(info->name); 230aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts // false to stop processing 231aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts rc = false; 232aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts } 233aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts 234aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts packagelist_free(info); 235aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts return rc; 236aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts} 237aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts 238501c373916e292764400dbae735f44b33378400fMark Salyzynstatic void* reinit_thread_start(void* /*obj*/) { 23911e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn prctl(PR_SET_NAME, "logd.daemon"); 24011e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn set_sched_policy(0, SP_BACKGROUND); 241d98f4e8af5076e6a9dbd4ddc2c375cb7bcda8cd8Riley Andrews setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND); 242e0fa291e898b451dc198ed52cebac3ffefac066eMark Salyzyn 243d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn cap_t caps = cap_init(); 244d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn (void)cap_clear(caps); 245d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn (void)cap_set_proc(caps); 246d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn (void)cap_free(caps); 247d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn 248e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn // If we are AID_ROOT, we should drop to AID_LOGD+AID_SYSTEM, if we are 249e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn // anything else, we have even lesser privileges and accept our fate. Not 250e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn // worth checking for error returns setting this thread's privileges. 251501c373916e292764400dbae735f44b33378400fMark Salyzyn (void)setgid(AID_SYSTEM); // readonly access to /data/system/packages.list 252501c373916e292764400dbae735f44b33378400fMark Salyzyn (void)setuid(AID_LOGD); // access to everything logd, eg /data/misc/logd 25311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn 25411e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn while (reinit_running && !sem_wait(&reinit) && reinit_running) { 25508739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn // uidToName Privileged Worker 25608739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn if (uid) { 2570484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn name = nullptr; 25808739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn 2590484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn packagelist_parse(package_list_parser_cb, nullptr); 260aeca97ba1cb6fdc028dd2f1f984eebb40c85b1fcWilliam Roberts 26108739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn uid = 0; 26208739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn sem_post(&uidName); 26308739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn continue; 26408739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn } 26508739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn 266ccbadc6be015553357a4c50de48dea46cb1adcbaMark Salyzyn if (fdDmesg >= 0) { 267ccbadc6be015553357a4c50de48dea46cb1adcbaMark Salyzyn static const char reinit_message[] = { KMSG_PRIORITY(LOG_INFO), 268501c373916e292764400dbae735f44b33378400fMark Salyzyn 'l', 269501c373916e292764400dbae735f44b33378400fMark Salyzyn 'o', 270501c373916e292764400dbae735f44b33378400fMark Salyzyn 'g', 271501c373916e292764400dbae735f44b33378400fMark Salyzyn 'd', 272501c373916e292764400dbae735f44b33378400fMark Salyzyn '.', 273501c373916e292764400dbae735f44b33378400fMark Salyzyn 'd', 274501c373916e292764400dbae735f44b33378400fMark Salyzyn 'a', 275501c373916e292764400dbae735f44b33378400fMark Salyzyn 'e', 276501c373916e292764400dbae735f44b33378400fMark Salyzyn 'm', 277501c373916e292764400dbae735f44b33378400fMark Salyzyn 'o', 278501c373916e292764400dbae735f44b33378400fMark Salyzyn 'n', 279501c373916e292764400dbae735f44b33378400fMark Salyzyn ':', 280501c373916e292764400dbae735f44b33378400fMark Salyzyn ' ', 281501c373916e292764400dbae735f44b33378400fMark Salyzyn 'r', 282501c373916e292764400dbae735f44b33378400fMark Salyzyn 'e', 283501c373916e292764400dbae735f44b33378400fMark Salyzyn 'i', 284501c373916e292764400dbae735f44b33378400fMark Salyzyn 'n', 285501c373916e292764400dbae735f44b33378400fMark Salyzyn 'i', 286501c373916e292764400dbae735f44b33378400fMark Salyzyn 't', 287501c373916e292764400dbae735f44b33378400fMark Salyzyn '\n' }; 288ccbadc6be015553357a4c50de48dea46cb1adcbaMark Salyzyn write(fdDmesg, reinit_message, sizeof(reinit_message)); 289ccbadc6be015553357a4c50de48dea46cb1adcbaMark Salyzyn } 290ccbadc6be015553357a4c50de48dea46cb1adcbaMark Salyzyn 29111e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn // Anything that reads persist.<property> 29211e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn if (logBuf) { 29311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn logBuf->init(); 2940484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn logBuf->initPrune(nullptr); 29511e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn } 29661e9ce6709a12cf39a9471476da3d50339efe466Mark Salyzyn android::ReReadEventLogTags(); 29711e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn } 29811e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn 2990484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn return nullptr; 30011e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn} 30111e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn 30295108f18443f22440653bf1648c969816ca852ddMark Salyzynstatic sem_t sem_name; 30395108f18443f22440653bf1648c969816ca852ddMark Salyzyn 304501c373916e292764400dbae735f44b33378400fMark Salyzynchar* android::uidToName(uid_t u) { 30508739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn if (!u || !reinit_running) { 3060484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn return nullptr; 30708739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn } 30808739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn 30995108f18443f22440653bf1648c969816ca852ddMark Salyzyn sem_wait(&sem_name); 31095108f18443f22440653bf1648c969816ca852ddMark Salyzyn 31195108f18443f22440653bf1648c969816ca852ddMark Salyzyn // Not multi-thread safe, we use sem_name to protect 31208739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn uid = u; 31308739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn 3140484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn name = nullptr; 31508739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn sem_post(&reinit); 31608739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn sem_wait(&uidName); 317501c373916e292764400dbae735f44b33378400fMark Salyzyn char* ret = name; 31895108f18443f22440653bf1648c969816ca852ddMark Salyzyn 31995108f18443f22440653bf1648c969816ca852ddMark Salyzyn sem_post(&sem_name); 32095108f18443f22440653bf1648c969816ca852ddMark Salyzyn 32195108f18443f22440653bf1648c969816ca852ddMark Salyzyn return ret; 32208739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn} 32308739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn 32411e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn// Serves as a global method to trigger reinitialization 32511e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn// and as a function that can be provided to signal(). 32611e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzynvoid reinit_signal_handler(int /*signal*/) { 32711e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn sem_post(&reinit); 32811e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn} 32911e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn 330501c373916e292764400dbae735f44b33378400fMark Salyzynstatic void readDmesg(LogAudit* al, LogKlog* kl) { 331d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn if (!al && !kl) { 332d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn return; 333d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn } 334d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn 3350484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn int rc = klogctl(KLOG_SIZE_BUFFER, nullptr, 0); 336ea1a24110767d6d5666fda8a19dd0b3f954068d6Mark Salyzyn if (rc <= 0) { 337d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn return; 338d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn } 339d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn 3400484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn // Margin for additional input race or trailing nul 3410484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn ssize_t len = rc + 1024; 342501c373916e292764400dbae735f44b33378400fMark Salyzyn std::unique_ptr<char[]> buf(new char[len]); 343d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn 344ea1a24110767d6d5666fda8a19dd0b3f954068d6Mark Salyzyn rc = klogctl(KLOG_READ_ALL, buf.get(), len); 345d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn if (rc <= 0) { 346d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn return; 347d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn } 348d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn 3490484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn if (rc < len) { 350d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn len = rc + 1; 351d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn } 352ea1a24110767d6d5666fda8a19dd0b3f954068d6Mark Salyzyn buf[--len] = '\0'; 353d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn 354b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn if (kl && kl->isMonotonic()) { 355151beac76d372c5c1bd71e656a6cfbd177e36509Mark Salyzyn kl->synchronize(buf.get(), len); 356d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn } 357d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn 3580484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn ssize_t sublen; 3590484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn for (char *ptr = nullptr, *tok = buf.get(); 3600484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn (rc >= 0) && !!(tok = android::log_strntok_r(tok, len, ptr, sublen)); 3610484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn tok = nullptr) { 3620484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn if ((sublen <= 0) || !*tok) continue; 363d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn if (al) { 364151beac76d372c5c1bd71e656a6cfbd177e36509Mark Salyzyn rc = al->log(tok, sublen); 365d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn } 366d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn if (kl) { 367151beac76d372c5c1bd71e656a6cfbd177e36509Mark Salyzyn rc = kl->log(tok, sublen); 368d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn } 369d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn } 370d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn} 371d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn 372d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzynstatic int issueReinit() { 373d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn cap_t caps = cap_init(); 374d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn (void)cap_clear(caps); 375d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn (void)cap_set_proc(caps); 376d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn (void)cap_free(caps); 377d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn 378501c373916e292764400dbae735f44b33378400fMark Salyzyn int sock = TEMP_FAILURE_RETRY(socket_local_client( 379501c373916e292764400dbae735f44b33378400fMark Salyzyn "logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM)); 380d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn if (sock < 0) return -errno; 381d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn 382d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn static const char reinitStr[] = "reinit"; 383d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinitStr, sizeof(reinitStr))); 384d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn if (ret < 0) return -errno; 385d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn 386d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn struct pollfd p; 387d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn memset(&p, 0, sizeof(p)); 388d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn p.fd = sock; 389d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn p.events = POLLIN; 390d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn ret = TEMP_FAILURE_RETRY(poll(&p, 1, 1000)); 391d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn if (ret < 0) return -errno; 392d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn if ((ret == 0) || !(p.revents & POLLIN)) return -ETIME; 393d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn 394d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn static const char success[] = "success"; 395d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn char buffer[sizeof(success) - 1]; 396d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn memset(buffer, 0, sizeof(buffer)); 397d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); 398d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn if (ret < 0) return -errno; 399d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn 400d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn return strncmp(buffer, success, sizeof(success) - 1) != 0; 401d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn} 402d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn 40311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn// Foreground waits for exit of the main persistent threads 40411e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn// that are started here. The threads are created to manage 40511e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn// UNIX domain client sockets for writing, reading and 40611e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn// controlling the user space logger, and for any additional 40711e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn// logging plugins like auditd and restart control. Additional 40811e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn// transitory per-client threads are created for each reader. 409501c373916e292764400dbae735f44b33378400fMark Salyzynint main(int argc, char* argv[]) { 41011e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn // issue reinit command. KISS argument parsing. 41111e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { 412d8f01807b8a49496256ccd75d49e0fd6be576424Mark Salyzyn return issueReinit(); 41311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn } 41411e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn 415e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn static const char dev_kmsg[] = "/dev/kmsg"; 416e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn fdDmesg = android_get_control_file(dev_kmsg); 417e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn if (fdDmesg < 0) { 418e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn fdDmesg = TEMP_FAILURE_RETRY(open(dev_kmsg, O_WRONLY | O_CLOEXEC)); 419e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn } 420e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn 421e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn int fdPmesg = -1; 422501c373916e292764400dbae735f44b33378400fMark Salyzyn bool klogd = __android_logger_property_get_bool( 423501c373916e292764400dbae735f44b33378400fMark Salyzyn "logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | 424501c373916e292764400dbae735f44b33378400fMark Salyzyn BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE); 425e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn if (klogd) { 426e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn static const char proc_kmsg[] = "/proc/kmsg"; 427e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn fdPmesg = android_get_control_file(proc_kmsg); 428e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn if (fdPmesg < 0) { 429501c373916e292764400dbae735f44b33378400fMark Salyzyn fdPmesg = TEMP_FAILURE_RETRY( 430501c373916e292764400dbae735f44b33378400fMark Salyzyn open(proc_kmsg, O_RDONLY | O_NDELAY | O_CLOEXEC)); 431e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn } 432e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn if (fdPmesg < 0) android::prdebug("Failed to open %s\n", proc_kmsg); 433e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn } 434e0b8ccd1a3db7059c56322ad6cbcb7d7c34c2954Mark Salyzyn 43511e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn // Reinit Thread 43611e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn sem_init(&reinit, 0, 0); 43708739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn sem_init(&uidName, 0, 0); 43895108f18443f22440653bf1648c969816ca852ddMark Salyzyn sem_init(&sem_name, 0, 1); 43911e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn pthread_attr_t attr; 44011e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn if (!pthread_attr_init(&attr)) { 44111e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn struct sched_param param; 44211e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn 44311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn memset(¶m, 0, sizeof(param)); 44411e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn pthread_attr_setschedparam(&attr, ¶m); 44511e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn pthread_attr_setschedpolicy(&attr, SCHED_BATCH); 446501c373916e292764400dbae735f44b33378400fMark Salyzyn if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { 44711e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn pthread_t thread; 44811e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn reinit_running = true; 4490484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn if (pthread_create(&thread, &attr, reinit_thread_start, nullptr)) { 45011e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn reinit_running = false; 45111e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn } 45211e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn } 45311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn pthread_attr_destroy(&attr); 454e9bebd0eb1845f0c6009ce2edc5aeb47bf89e397Mark Salyzyn } 455e9bebd0eb1845f0c6009ce2edc5aeb47bf89e397Mark Salyzyn 456501c373916e292764400dbae735f44b33378400fMark Salyzyn bool auditd = 457501c373916e292764400dbae735f44b33378400fMark Salyzyn __android_logger_property_get_bool("ro.logd.auditd", BOOL_DEFAULT_TRUE); 458d2b3291ffa1cd9c2214b4a68d72508461de57e48Mark Salyzyn if (drop_privs(klogd, auditd) != 0) { 4590175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return -1; 4600175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 4610175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 4620175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // Serves the purpose of managing the last logs times read on a 4630175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // socket connection, and as a reader lock on a range of log 4640175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // entries. 4650175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 466501c373916e292764400dbae735f44b33378400fMark Salyzyn LastLogTimes* times = new LastLogTimes(); 4670175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 4680175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // LogBuffer is the object which is responsible for holding all 4690175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // log entries. 4700175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 47111e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn logBuf = new LogBuffer(times); 47211e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn 47311e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn signal(SIGHUP, reinit_signal_handler); 4740175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 475501c373916e292764400dbae735f44b33378400fMark Salyzyn if (__android_logger_property_get_bool( 476501c373916e292764400dbae735f44b33378400fMark Salyzyn "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | 477501c373916e292764400dbae735f44b33378400fMark Salyzyn BOOL_DEFAULT_FLAG_ENG | 478501c373916e292764400dbae735f44b33378400fMark Salyzyn BOOL_DEFAULT_FLAG_SVELTE)) { 479a1aacb71f387c91d5fe383b8aaa5b0be2ec9cd3cMark Salyzyn logBuf->enableStatistics(); 480f5fc50958978fc039bc3207cbfcb140a277442ebMark Salyzyn } 481e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn 4820175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // LogReader listens on /dev/socket/logdr. When a client 4830175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // connects, log entries in the LogBuffer are written to the client. 4840175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 485501c373916e292764400dbae735f44b33378400fMark Salyzyn LogReader* reader = new LogReader(logBuf); 4860175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (reader->startListener()) { 4870175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn exit(1); 4880175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 4890175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 4900175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // LogListener listens on /dev/socket/logdw for client 4910175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // initiated log messages. New log entries are added to LogBuffer 4920175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // and LogReader is notified to send updates to connected clients. 4930175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 494501c373916e292764400dbae735f44b33378400fMark Salyzyn LogListener* swl = new LogListener(logBuf, reader); 495581edc1b6c3799238cfb674dfddb97db44f2818eMark Salyzyn // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value 49639944c89a9223ee646cd9263317b284149baa4f1Mark Salyzyn if (swl->startListener(600)) { 4970175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn exit(1); 4980175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 4990175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 5000175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // Command listener listens on /dev/socket/logd for incoming logd 5010175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // administrative commands. 5020175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 503501c373916e292764400dbae735f44b33378400fMark Salyzyn CommandListener* cl = new CommandListener(logBuf, reader, swl); 5040175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (cl->startListener()) { 5050175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn exit(1); 5060175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 5070175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 50829d238d2a8e12c131a4cfbccb912e525cca6b10dWilliam Roberts // LogAudit listens on NETLINK_AUDIT socket for selinux 50929d238d2a8e12c131a4cfbccb912e525cca6b10dWilliam Roberts // initiated log messages. New log entries are added to LogBuffer 51029d238d2a8e12c131a4cfbccb912e525cca6b10dWilliam Roberts // and LogReader is notified to send updates to connected clients. 51129d238d2a8e12c131a4cfbccb912e525cca6b10dWilliam Roberts 5120484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn LogAudit* al = nullptr; 513a742d1027784a54c535cff69b375a9f560893155Sami Tolvanen if (auditd) { 514a742d1027784a54c535cff69b375a9f560893155Sami Tolvanen al = new LogAudit(logBuf, reader, 515f10e27379064797acb2659afc45b54eafbfcd019Mark Salyzyn __android_logger_property_get_bool( 516501c373916e292764400dbae735f44b33378400fMark Salyzyn "ro.logd.auditd.dmesg", BOOL_DEFAULT_TRUE) 517501c373916e292764400dbae735f44b33378400fMark Salyzyn ? fdDmesg 518501c373916e292764400dbae735f44b33378400fMark Salyzyn : -1); 519a742d1027784a54c535cff69b375a9f560893155Sami Tolvanen } 52011e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn 5210484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn LogKlog* kl = nullptr; 522a1aacb71f387c91d5fe383b8aaa5b0be2ec9cd3cMark Salyzyn if (klogd) { 5230484b3b5757594a43c6b646824b44643d2a007deMark Salyzyn kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != nullptr); 524a1aacb71f387c91d5fe383b8aaa5b0be2ec9cd3cMark Salyzyn } 525eb06de716b4f33e9fdb1c41f0cce61084545bfd5Mark Salyzyn 526a742d1027784a54c535cff69b375a9f560893155Sami Tolvanen readDmesg(al, kl); 527eb06de716b4f33e9fdb1c41f0cce61084545bfd5Mark Salyzyn 528d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn // failure is an option ... messages are in dmesg (required by standard) 529a1aacb71f387c91d5fe383b8aaa5b0be2ec9cd3cMark Salyzyn 530d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn if (kl && kl->startListener()) { 531d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn delete kl; 532d5600fd40fac5e90532ea08e22940965cfdd7710Mark Salyzyn } 533a1aacb71f387c91d5fe383b8aaa5b0be2ec9cd3cMark Salyzyn 534a742d1027784a54c535cff69b375a9f560893155Sami Tolvanen if (al && al->startListener()) { 535a742d1027784a54c535cff69b375a9f560893155Sami Tolvanen delete al; 53629d238d2a8e12c131a4cfbccb912e525cca6b10dWilliam Roberts } 53729d238d2a8e12c131a4cfbccb912e525cca6b10dWilliam Roberts 53811e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn TEMP_FAILURE_RETRY(pause()); 53911e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn 5400175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn exit(0); 5410175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn} 542