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(&param, 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, &param) < 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(&param, 0, sizeof(param));
44411e55cb9c1e5efe553e36f1b5c04ab21883f66e1Mark Salyzyn        pthread_attr_setschedparam(&attr, &param);
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