blob: 20578861b4af6ffe06b45e0c0e0f7c625b96975e [file] [log] [blame]
Mark Salyzyn12bac902014-02-26 09:50:16 -08001/*
2 * Copyright (C) 2012-2014 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
Mark Salyzyn59d09102014-04-28 16:39:04 -070017#include <limits.h>
Mark Salyzynd89faa82016-01-12 10:08:03 -080018#include <sys/cdefs.h>
Mark Salyzyn4e5efdc2014-04-28 14:07:23 -070019#include <sys/prctl.h>
Mark Salyzyn12bac902014-02-26 09:50:16 -080020#include <sys/socket.h>
21#include <sys/types.h>
22#include <sys/un.h>
23#include <unistd.h>
24
Tom Cherry7955fd42020-05-06 12:04:09 -070025#include <thread>
26
Mark Salyzyn12bac902014-02-26 09:50:16 -080027#include <cutils/sockets.h>
Mark Salyzynb4853952015-03-17 07:56:32 -070028#include <private/android_filesystem_config.h>
Mark Salyzyn6904e182015-01-16 13:38:07 -080029#include <private/android_logger.h>
Mark Salyzyn12bac902014-02-26 09:50:16 -080030
Mark Salyzyn1d21d542016-02-23 08:55:43 -080031#include "LogBuffer.h"
Mark Salyzyn12bac902014-02-26 09:50:16 -080032#include "LogListener.h"
Mark Salyzync9690862015-12-04 10:59:45 -080033#include "LogUtils.h"
Mark Salyzyn12bac902014-02-26 09:50:16 -080034
Tom Cherry5ecfbf02020-05-11 16:29:29 -070035LogListener::LogListener(LogBuffer* buf) : socket_(GetLogSocket()), logbuf_(buf) {}
Mark Salyzyn12bac902014-02-26 09:50:16 -080036
Tom Cherry7955fd42020-05-06 12:04:09 -070037bool LogListener::StartListener() {
38 if (socket_ <= 0) {
39 return false;
40 }
41 auto thread = std::thread(&LogListener::ThreadFunction, this);
42 thread.detach();
43 return true;
44}
45
46void LogListener::ThreadFunction() {
Mark Salyzynb4853952015-03-17 07:56:32 -070047 static bool name_set;
48 if (!name_set) {
49 prctl(PR_SET_NAME, "logd.writer");
50 name_set = true;
51 }
Mark Salyzyn4e5efdc2014-04-28 14:07:23 -070052
Tom Cherry7955fd42020-05-06 12:04:09 -070053 while (true) {
54 HandleData();
55 }
56}
57
58void LogListener::HandleData() {
Paul Elliott043810b2017-11-07 11:11:41 +000059 // + 1 to ensure null terminator if MAX_PAYLOAD buffer is received
Tom Cherry7955fd42020-05-06 12:04:09 -070060 __attribute__((uninitialized)) char
61 buffer[sizeof(android_log_header_t) + LOGGER_ENTRY_MAX_PAYLOAD + 1];
62 struct iovec iov = {buffer, sizeof(buffer) - 1};
Mark Salyzyn12bac902014-02-26 09:50:16 -080063
Elliott Hughes273936a2016-06-06 19:56:24 -070064 alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))];
Mark Salyzyn12bac902014-02-26 09:50:16 -080065 struct msghdr hdr = {
Yi Kong36feb152018-07-13 17:39:22 -070066 nullptr, 0, &iov, 1, control, sizeof(control), 0,
Mark Salyzyn12bac902014-02-26 09:50:16 -080067 };
68
Mark Salyzynf9d20d12015-12-15 12:30:46 -080069 // To clear the entire buffer is secure/safe, but this contributes to 1.68%
Paul Elliott043810b2017-11-07 11:11:41 +000070 // overhead under logging load. We are safe because we check counts, but
71 // still need to clear null terminator
Mark Salyzynf9d20d12015-12-15 12:30:46 -080072 // memset(buffer, 0, sizeof(buffer));
Tom Cherry7955fd42020-05-06 12:04:09 -070073 ssize_t n = recvmsg(socket_, &hdr, 0);
Mark Salyzyn6904e182015-01-16 13:38:07 -080074 if (n <= (ssize_t)(sizeof(android_log_header_t))) {
Tom Cherry7955fd42020-05-06 12:04:09 -070075 return;
Mark Salyzyn12bac902014-02-26 09:50:16 -080076 }
77
Paul Elliott043810b2017-11-07 11:11:41 +000078 buffer[n] = 0;
79
Yi Kong36feb152018-07-13 17:39:22 -070080 struct ucred* cred = nullptr;
Mark Salyzyn12bac902014-02-26 09:50:16 -080081
Mark Salyzyn65059532017-03-10 14:31:54 -080082 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
Yi Kong36feb152018-07-13 17:39:22 -070083 while (cmsg != nullptr) {
Mark Salyzyn65059532017-03-10 14:31:54 -080084 if (cmsg->cmsg_level == SOL_SOCKET &&
85 cmsg->cmsg_type == SCM_CREDENTIALS) {
86 cred = (struct ucred*)CMSG_DATA(cmsg);
Mark Salyzyn12bac902014-02-26 09:50:16 -080087 break;
88 }
89 cmsg = CMSG_NXTHDR(&hdr, cmsg);
90 }
91
Yi Kong36feb152018-07-13 17:39:22 -070092 if (cred == nullptr) {
Tom Cherry7955fd42020-05-06 12:04:09 -070093 return;
Mark Salyzyn12bac902014-02-26 09:50:16 -080094 }
95
Mark Salyzynb4853952015-03-17 07:56:32 -070096 if (cred->uid == AID_LOGD) {
Mark Salyzyn12bac902014-02-26 09:50:16 -080097 // ignore log messages we send to ourself.
98 // Such log messages are often generated by libraries we depend on
99 // which use standard Android logging.
Tom Cherry7955fd42020-05-06 12:04:09 -0700100 return;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800101 }
102
Mark Salyzyn65059532017-03-10 14:31:54 -0800103 android_log_header_t* header =
104 reinterpret_cast<android_log_header_t*>(buffer);
Hao Wang10d19f62017-12-04 14:10:40 +0800105 log_id_t logId = static_cast<log_id_t>(header->id);
106 if (/* logId < LOG_ID_MIN || */ logId >= LOG_ID_MAX ||
107 logId == LOG_ID_KERNEL) {
Tom Cherry7955fd42020-05-06 12:04:09 -0700108 return;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800109 }
Mark Salyzyn12bac902014-02-26 09:50:16 -0800110
Hao Wang10d19f62017-12-04 14:10:40 +0800111 if ((logId == LOG_ID_SECURITY) &&
Mark Salyzyn65059532017-03-10 14:31:54 -0800112 (!__android_log_security() ||
113 !clientHasLogCredentials(cred->uid, cred->gid, cred->pid))) {
Tom Cherry7955fd42020-05-06 12:04:09 -0700114 return;
Mark Salyzync9690862015-12-04 10:59:45 -0800115 }
116
Mark Salyzyn65059532017-03-10 14:31:54 -0800117 char* msg = ((char*)buffer) + sizeof(android_log_header_t);
Mark Salyzyn6904e182015-01-16 13:38:07 -0800118 n -= sizeof(android_log_header_t);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800119
Mark Salyzyn63a4ad52014-03-21 13:12:16 -0700120 // NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a
121 // truncated message to the logs.
Mark Salyzyn59d09102014-04-28 16:39:04 -0700122
Tom Cherry5ecfbf02020-05-11 16:29:29 -0700123 logbuf_->log(logId, header->realtime, cred->uid, cred->pid, header->tid, msg,
124 ((size_t)n <= UINT16_MAX) ? (uint16_t)n : UINT16_MAX);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800125}
126
Tom Cherry7955fd42020-05-06 12:04:09 -0700127int LogListener::GetLogSocket() {
Mark Salyzyn3f6151e2014-03-24 10:26:47 -0700128 static const char socketName[] = "logdw";
129 int sock = android_get_control_socket(socketName);
130
Mark Salyzync4619012017-05-05 15:32:10 -0700131 if (sock < 0) { // logd started up in init.sh
Mark Salyzyn65059532017-03-10 14:31:54 -0800132 sock = socket_local_server(
133 socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM);
Mark Salyzyn3f6151e2014-03-24 10:26:47 -0700134
Mark Salyzync4619012017-05-05 15:32:10 -0700135 int on = 1;
136 if (setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on))) {
137 return -1;
138 }
Mark Salyzyn12bac902014-02-26 09:50:16 -0800139 }
140 return sock;
141}