blob: 46b65679a439e73d3ba85867aae90d86fa5a9129 [file] [log] [blame]
Mark Salyzyn0175b072014-02-26 09:50:16 -08001/*
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>
Tom Cherry0b2a0112019-06-06 13:41:20 -070020#include <linux/capability.h>
Mark Salyzyn11e55cb2015-03-10 16:45:17 -070021#include <poll.h>
Mark Salyzyn882f8562013-12-26 15:13:36 -080022#include <sched.h>
Mark Salyzyn11e55cb2015-03-10 16:45:17 -070023#include <semaphore.h>
24#include <signal.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080025#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <sys/capability.h>
Mark Salyzyneb06de72014-10-13 09:59:37 -070029#include <sys/klog.h>
Elliott Hughese5a0f202014-07-18 17:39:41 -070030#include <sys/prctl.h>
Riley Andrewsd98f4e82015-06-08 23:36:34 -070031#include <sys/resource.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080032#include <sys/stat.h>
33#include <sys/types.h>
Mark Salyzynccbadc62015-03-12 12:25:35 -070034#include <syslog.h>
Mark Salyzyne457b742014-02-19 17:18:31 -080035#include <unistd.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080036
Mark Salyzynd5600fd2015-06-12 14:59:42 -070037#include <memory>
38
Tom Cherryf93b4002020-06-03 09:23:49 -070039#include <android-base/logging.h>
Jorge Lucangeli Obes2bbdbe82016-07-15 13:57:08 -040040#include <android-base/macros.h>
Tom Cherryf93b4002020-06-03 09:23:49 -070041#include <android-base/stringprintf.h>
Mark Salyzyn52bd37e2016-11-07 09:39:30 -080042#include <cutils/android_get_control_file.h>
Mark Salyzyn11e55cb2015-03-10 16:45:17 -070043#include <cutils/sockets.h>
Mark Salyzynff32f3c2015-04-13 14:24:45 -070044#include <log/event_tag_map.h>
William Robertsaeca97b2015-07-31 13:10:36 -070045#include <packagelistparser/packagelistparser.h>
Mark Salyzyne3aeeee2015-03-17 07:56:32 -070046#include <private/android_filesystem_config.h>
Mark Salyzyn5740a462016-03-28 15:42:08 -070047#include <private/android_logger.h>
Suren Baghdasaryan02843332018-12-21 12:30:16 -080048#include <processgroup/sched_policy.h>
Riley Andrewsd98f4e82015-06-08 23:36:34 -070049#include <utils/threads.h>
Mark Salyzyne457b742014-02-19 17:18:31 -080050
Tom Cherryd5b38382020-05-12 13:16:41 -070051#include "ChattyLogBuffer.h"
Mark Salyzyn0175b072014-02-26 09:50:16 -080052#include "CommandListener.h"
William Roberts29d238d2013-02-08 09:45:26 +090053#include "LogAudit.h"
Mark Salyzyn501c3732017-03-10 14:31:54 -080054#include "LogBuffer.h"
Mark Salyzyna1aacb72014-10-15 08:49:39 -070055#include "LogKlog.h"
Mark Salyzyn501c3732017-03-10 14:31:54 -080056#include "LogListener.h"
Tom Cherry283c9a12020-05-14 19:25:05 -070057#include "LogReader.h"
Tom Cherry64e90162020-05-07 14:44:43 -070058#include "LogStatistics.h"
Tom Cherry1a12ae32020-05-01 16:13:18 -070059#include "LogTags.h"
Mark Salyzyn5ac5c6b2015-08-28 08:02:59 -070060#include "LogUtils.h"
Tom Cherry1a796bc2020-05-13 09:28:37 -070061#include "SerializedLogBuffer.h"
Tom Cherry8f613462020-05-12 12:46:43 -070062#include "SimpleLogBuffer.h"
Mark Salyzyn0175b072014-02-26 09:50:16 -080063
Mark Salyzyn501c3732017-03-10 14:31:54 -080064#define KMSG_PRIORITY(PRI) \
65 '<', '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) / 10, \
66 '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) % 10, '>'
Mark Salyzynccbadc62015-03-12 12:25:35 -070067
Tom Cherry0b2a0112019-06-06 13:41:20 -070068// The service is designed to be run by init, it does not respond well to starting up manually. Init
69// has a 'sigstop' feature that sends SIGSTOP to a service immediately before calling exec(). This
70// allows debuggers, etc to be attached to logd at the very beginning, while still having init
71// handle the user, groups, capabilities, files, etc setup.
Mark Salyzynd2b32912016-10-28 15:11:46 -070072static int drop_privs(bool klogd, bool auditd) {
Elliott Hughescef62b42018-06-13 10:33:45 -070073 sched_param param = {};
Mark Salyzyn882f8562013-12-26 15:13:36 -080074
Mark Salyzyn56ba4b52015-01-30 15:19:48 -080075 if (set_sched_policy(0, SP_BACKGROUND) < 0) {
Tom Cherryf93b4002020-06-03 09:23:49 -070076 PLOG(ERROR) << "failed to set background scheduling policy";
Elliott Hughescef62b42018-06-13 10:33:45 -070077 return -1;
Mark Salyzyn56ba4b52015-01-30 15:19:48 -080078 }
79
Mark Salyzyn501c3732017-03-10 14:31:54 -080080 if (sched_setscheduler((pid_t)0, SCHED_BATCH, &param) < 0) {
Tom Cherryf93b4002020-06-03 09:23:49 -070081 PLOG(ERROR) << "failed to set batch scheduler";
Elliott Hughescef62b42018-06-13 10:33:45 -070082 return -1;
Mark Salyzyn882f8562013-12-26 15:13:36 -080083 }
84
Tom Cherryf93b4002020-06-03 09:23:49 -070085 if (!__android_logger_property_get_bool("ro.debuggable", BOOL_DEFAULT_FALSE) &&
Elliott Hughescef62b42018-06-13 10:33:45 -070086 prctl(PR_SET_DUMPABLE, 0) == -1) {
Tom Cherryf93b4002020-06-03 09:23:49 -070087 PLOG(ERROR) << "failed to clear PR_SET_DUMPABLE";
Mark Salyzyn6a70ded2016-10-28 14:49:53 -070088 return -1;
89 }
90
Tom Cherry0b2a0112019-06-06 13:41:20 -070091 std::unique_ptr<struct _cap_struct, int (*)(void*)> caps(cap_init(), cap_free);
92 if (cap_clear(caps.get()) < 0) {
Mark Salyzyn501c3732017-03-10 14:31:54 -080093 return -1;
94 }
Tom Cherry0b2a0112019-06-06 13:41:20 -070095 std::vector<cap_value_t> cap_value;
96 if (klogd) {
97 cap_value.emplace_back(CAP_SYSLOG);
98 }
99 if (auditd) {
100 cap_value.emplace_back(CAP_AUDIT_CONTROL);
101 }
102
103 if (cap_set_flag(caps.get(), CAP_PERMITTED, cap_value.size(), cap_value.data(), CAP_SET) < 0) {
104 return -1;
105 }
106 if (cap_set_flag(caps.get(), CAP_EFFECTIVE, cap_value.size(), cap_value.data(), CAP_SET) < 0) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800107 return -1;
108 }
Mark Salyzynf0b8e1b2016-10-28 14:49:53 -0700109 if (cap_set_proc(caps.get()) < 0) {
Tom Cherryf93b4002020-06-03 09:23:49 -0700110 PLOG(ERROR) << "failed to set CAP_SYSLOG or CAP_AUDIT_CONTROL";
Elliott Hughescef62b42018-06-13 10:33:45 -0700111 return -1;
Mark Salyzynf0b8e1b2016-10-28 14:49:53 -0700112 }
113
Mark Salyzyn0175b072014-02-26 09:50:16 -0800114 return 0;
115}
116
Mark Salyzyn501c3732017-03-10 14:31:54 -0800117char* android::uidToName(uid_t u) {
Tom Cherry36f53992017-09-06 10:07:37 -0700118 struct Userdata {
119 uid_t uid;
120 char* name;
121 } userdata = {
122 .uid = u,
123 .name = nullptr,
124 };
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700125
Tom Cherry36f53992017-09-06 10:07:37 -0700126 packagelist_parse(
127 [](pkg_info* info, void* callback_parameter) {
128 auto userdata = reinterpret_cast<Userdata*>(callback_parameter);
129 bool result = true;
130 if (info->uid == userdata->uid) {
131 userdata->name = strdup(info->name);
132 // false to stop processing
133 result = false;
134 }
135 packagelist_free(info);
136 return result;
137 },
138 &userdata);
Mark Salyzyn95108f12015-04-20 07:26:27 -0700139
Tom Cherry36f53992017-09-06 10:07:37 -0700140 return userdata.name;
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700141}
142
Mark Salyzyn501c3732017-03-10 14:31:54 -0800143static void readDmesg(LogAudit* al, LogKlog* kl) {
Mark Salyzynd5600fd2015-06-12 14:59:42 -0700144 if (!al && !kl) {
145 return;
146 }
147
Mark Salyzyn0484b3b2016-08-11 08:02:06 -0700148 int rc = klogctl(KLOG_SIZE_BUFFER, nullptr, 0);
Mark Salyzynd5600fd2015-06-12 14:59:42 -0700149 if (rc <= 0) {
150 return;
151 }
152
Mark Salyzyn0484b3b2016-08-11 08:02:06 -0700153 // Margin for additional input race or trailing nul
154 ssize_t len = rc + 1024;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800155 std::unique_ptr<char[]> buf(new char[len]);
Mark Salyzynea1a2412015-09-02 07:39:53 -0700156
157 rc = klogctl(KLOG_READ_ALL, buf.get(), len);
158 if (rc <= 0) {
159 return;
160 }
161
Mark Salyzyn0484b3b2016-08-11 08:02:06 -0700162 if (rc < len) {
Mark Salyzynd5600fd2015-06-12 14:59:42 -0700163 len = rc + 1;
164 }
Mark Salyzynea1a2412015-09-02 07:39:53 -0700165 buf[--len] = '\0';
Mark Salyzynd5600fd2015-06-12 14:59:42 -0700166
Mark Salyzyn0484b3b2016-08-11 08:02:06 -0700167 ssize_t sublen;
168 for (char *ptr = nullptr, *tok = buf.get();
169 (rc >= 0) && !!(tok = android::log_strntok_r(tok, len, ptr, sublen));
170 tok = nullptr) {
171 if ((sublen <= 0) || !*tok) continue;
Mark Salyzynd5600fd2015-06-12 14:59:42 -0700172 if (al) {
Mark Salyzyn151beac2015-09-04 11:37:42 -0700173 rc = al->log(tok, sublen);
Mark Salyzynd5600fd2015-06-12 14:59:42 -0700174 }
175 if (kl) {
Mark Salyzyn151beac2015-09-04 11:37:42 -0700176 rc = kl->log(tok, sublen);
Mark Salyzynd5600fd2015-06-12 14:59:42 -0700177 }
178 }
179}
180
Mark Salyzynd8f01802016-10-31 13:49:44 -0700181static int issueReinit() {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800182 int sock = TEMP_FAILURE_RETRY(socket_local_client(
183 "logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM));
Mark Salyzynd8f01802016-10-31 13:49:44 -0700184 if (sock < 0) return -errno;
185
186 static const char reinitStr[] = "reinit";
187 ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinitStr, sizeof(reinitStr)));
188 if (ret < 0) return -errno;
189
190 struct pollfd p;
191 memset(&p, 0, sizeof(p));
192 p.fd = sock;
193 p.events = POLLIN;
194 ret = TEMP_FAILURE_RETRY(poll(&p, 1, 1000));
195 if (ret < 0) return -errno;
196 if ((ret == 0) || !(p.revents & POLLIN)) return -ETIME;
197
198 static const char success[] = "success";
199 char buffer[sizeof(success) - 1];
200 memset(buffer, 0, sizeof(buffer));
201 ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
202 if (ret < 0) return -errno;
203
204 return strncmp(buffer, success, sizeof(success) - 1) != 0;
205}
206
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700207// Foreground waits for exit of the main persistent threads
208// that are started here. The threads are created to manage
209// UNIX domain client sockets for writing, reading and
210// controlling the user space logger, and for any additional
211// logging plugins like auditd and restart control. Additional
212// transitory per-client threads are created for each reader.
Mark Salyzyn501c3732017-03-10 14:31:54 -0800213int main(int argc, char* argv[]) {
Hidehiko Abe352476e2017-03-29 17:41:17 +0900214 // logd is written under the assumption that the timezone is UTC.
215 // If TZ is not set, persist.sys.timezone is looked up in some time utility
216 // libc functions, including mktime. It confuses the logd time handling,
217 // so here explicitly set TZ to UTC, which overrides the property.
218 setenv("TZ", "UTC", 1);
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700219 // issue reinit command. KISS argument parsing.
220 if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) {
Mark Salyzynd8f01802016-10-31 13:49:44 -0700221 return issueReinit();
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700222 }
223
Tom Cherryf93b4002020-06-03 09:23:49 -0700224 android::base::InitLogging(
225 argv, [](android::base::LogId log_id, android::base::LogSeverity severity,
226 const char* tag, const char* file, unsigned int line, const char* message) {
227 if (tag && strcmp(tag, "logd") != 0) {
228 auto prefixed_message = android::base::StringPrintf("%s: %s", tag, message);
229 android::base::KernelLogger(log_id, severity, "logd", file, line,
230 prefixed_message.c_str());
231 } else {
232 android::base::KernelLogger(log_id, severity, "logd", file, line, message);
233 }
234 });
235
Mark Salyzyne0b8ccd2016-10-27 08:21:35 -0700236 static const char dev_kmsg[] = "/dev/kmsg";
Tom Cherryf93b4002020-06-03 09:23:49 -0700237 int fdDmesg = android_get_control_file(dev_kmsg);
Mark Salyzyne0b8ccd2016-10-27 08:21:35 -0700238 if (fdDmesg < 0) {
239 fdDmesg = TEMP_FAILURE_RETRY(open(dev_kmsg, O_WRONLY | O_CLOEXEC));
240 }
241
242 int fdPmesg = -1;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800243 bool klogd = __android_logger_property_get_bool(
Siarhei Vishniakoue8ed36b2017-12-28 14:13:22 -0800244 "ro.logd.kernel",
245 BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE);
Mark Salyzyne0b8ccd2016-10-27 08:21:35 -0700246 if (klogd) {
247 static const char proc_kmsg[] = "/proc/kmsg";
248 fdPmesg = android_get_control_file(proc_kmsg);
249 if (fdPmesg < 0) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800250 fdPmesg = TEMP_FAILURE_RETRY(
251 open(proc_kmsg, O_RDONLY | O_NDELAY | O_CLOEXEC));
Mark Salyzyne0b8ccd2016-10-27 08:21:35 -0700252 }
Tom Cherryf93b4002020-06-03 09:23:49 -0700253 if (fdPmesg < 0) PLOG(ERROR) << "Failed to open " << proc_kmsg;
Mark Salyzyne0b8ccd2016-10-27 08:21:35 -0700254 }
255
Tom Cherry0b2a0112019-06-06 13:41:20 -0700256 bool auditd = __android_logger_property_get_bool("ro.logd.auditd", BOOL_DEFAULT_TRUE);
257 if (drop_privs(klogd, auditd) != 0) {
258 return EXIT_FAILURE;
259 }
260
Tom Cherry1a12ae32020-05-01 16:13:18 -0700261 // A cache of event log tags
262 LogTags log_tags;
Tom Cherry68630a02020-05-11 16:29:29 -0700263
Tom Cherry5a3db392020-05-01 17:03:20 -0700264 // Pruning configuration.
265 PruneList prune_list;
Tom Cherry68630a02020-05-11 16:29:29 -0700266
Tom Cherry64e90162020-05-07 14:44:43 -0700267 // Partial (required for chatty) or full logging statistics.
268 bool enable_full_log_statistics = __android_logger_property_get_bool(
269 "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST |
270 BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE);
271 LogStatistics log_statistics(enable_full_log_statistics);
Tom Cherry1a12ae32020-05-01 16:13:18 -0700272
Mark Salyzyn0175b072014-02-26 09:50:16 -0800273 // Serves the purpose of managing the last logs times read on a
274 // socket connection, and as a reader lock on a range of log
275 // entries.
Tom Cherry68630a02020-05-11 16:29:29 -0700276 LogReaderList reader_list;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800277
Tom Cherry8f613462020-05-12 12:46:43 -0700278 // LogBuffer is the object which is responsible for holding all log entries.
279 LogBuffer* logBuf;
280 if (true) {
281 logBuf = new ChattyLogBuffer(&reader_list, &log_tags, &prune_list, &log_statistics);
282 } else {
283 logBuf = new SimpleLogBuffer(&reader_list, &log_tags, &log_statistics);
284 }
Mark Salyzyne457b742014-02-19 17:18:31 -0800285
Mark Salyzyn0175b072014-02-26 09:50:16 -0800286 // LogReader listens on /dev/socket/logdr. When a client
287 // connects, log entries in the LogBuffer are written to the client.
Tom Cherry68630a02020-05-11 16:29:29 -0700288 LogReader* reader = new LogReader(logBuf, &reader_list);
Mark Salyzyn0175b072014-02-26 09:50:16 -0800289 if (reader->startListener()) {
Elliott Hughescef62b42018-06-13 10:33:45 -0700290 return EXIT_FAILURE;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800291 }
292
293 // LogListener listens on /dev/socket/logdw for client
294 // initiated log messages. New log entries are added to LogBuffer
295 // and LogReader is notified to send updates to connected clients.
Tom Cherry68630a02020-05-11 16:29:29 -0700296 LogListener* swl = new LogListener(logBuf);
Tom Cherryc64dd8e2020-05-06 12:04:09 -0700297 if (!swl->StartListener()) {
Elliott Hughescef62b42018-06-13 10:33:45 -0700298 return EXIT_FAILURE;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800299 }
300
301 // Command listener listens on /dev/socket/logd for incoming logd
302 // administrative commands.
Tom Cherry64e90162020-05-07 14:44:43 -0700303 CommandListener* cl = new CommandListener(logBuf, &log_tags, &prune_list, &log_statistics);
Mark Salyzyn0175b072014-02-26 09:50:16 -0800304 if (cl->startListener()) {
Elliott Hughescef62b42018-06-13 10:33:45 -0700305 return EXIT_FAILURE;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800306 }
307
William Roberts29d238d2013-02-08 09:45:26 +0900308 // LogAudit listens on NETLINK_AUDIT socket for selinux
309 // initiated log messages. New log entries are added to LogBuffer
310 // and LogReader is notified to send updates to connected clients.
Mark Salyzyn0484b3b2016-08-11 08:02:06 -0700311 LogAudit* al = nullptr;
Sami Tolvanena742d102016-06-14 18:04:43 +0000312 if (auditd) {
Tom Cherry68630a02020-05-11 16:29:29 -0700313 int dmesg_fd = __android_logger_property_get_bool("ro.logd.auditd.dmesg", BOOL_DEFAULT_TRUE)
314 ? fdDmesg
315 : -1;
316 al = new LogAudit(logBuf, dmesg_fd, &log_statistics);
Sami Tolvanena742d102016-06-14 18:04:43 +0000317 }
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700318
Mark Salyzyn0484b3b2016-08-11 08:02:06 -0700319 LogKlog* kl = nullptr;
Mark Salyzyna1aacb72014-10-15 08:49:39 -0700320 if (klogd) {
Tom Cherry68630a02020-05-11 16:29:29 -0700321 kl = new LogKlog(logBuf, fdDmesg, fdPmesg, al != nullptr, &log_statistics);
Mark Salyzyna1aacb72014-10-15 08:49:39 -0700322 }
Mark Salyzyneb06de72014-10-13 09:59:37 -0700323
Sami Tolvanena742d102016-06-14 18:04:43 +0000324 readDmesg(al, kl);
Mark Salyzyneb06de72014-10-13 09:59:37 -0700325
Mark Salyzynd5600fd2015-06-12 14:59:42 -0700326 // failure is an option ... messages are in dmesg (required by standard)
Mark Salyzynd5600fd2015-06-12 14:59:42 -0700327 if (kl && kl->startListener()) {
328 delete kl;
329 }
Mark Salyzyneb06de72014-10-13 09:59:37 -0700330
Sami Tolvanena742d102016-06-14 18:04:43 +0000331 if (al && al->startListener()) {
332 delete al;
William Roberts29d238d2013-02-08 09:45:26 +0900333 }
334
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700335 TEMP_FAILURE_RETRY(pause());
336
Elliott Hughescef62b42018-06-13 10:33:45 -0700337 return EXIT_SUCCESS;
Mark Salyzyn0175b072014-02-26 09:50:16 -0800338}