10175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn/* 20175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Copyright (C) 2012-2014 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 17e0fa291e898b451dc198ed52cebac3ffefac066eMark Salyzyn#include <limits.h> 188daa9af02dc0e63ce220e3fa95bf5fe4d6b7a99aMark Salyzyn#include <sys/prctl.h> 190175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <sys/socket.h> 200175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <sys/types.h> 210175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <sys/un.h> 220175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <unistd.h> 230175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 240175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <cutils/sockets.h> 250175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <log/logger.h> 26e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn#include <private/android_filesystem_config.h> 27b5f6e45d6bddd2f6262bf387c3314dc744896320Mark Salyzyn#include <private/android_logger.h> 280175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 290175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include "LogListener.h" 300175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 3166091f11f427587bf810d89b0f64be556e1cd168Mark SalyzynLogListener::LogListener(LogBuffer *buf, LogReader *reader) : 3266091f11f427587bf810d89b0f64be556e1cd168Mark Salyzyn SocketListener(getLogSocket(), false), 3366091f11f427587bf810d89b0f64be556e1cd168Mark Salyzyn logbuf(buf), 3466091f11f427587bf810d89b0f64be556e1cd168Mark Salyzyn reader(reader) { 3566091f11f427587bf810d89b0f64be556e1cd168Mark Salyzyn} 360175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 370175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzynbool LogListener::onDataAvailable(SocketClient *cli) { 38e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn static bool name_set; 39e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn if (!name_set) { 40e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn prctl(PR_SET_NAME, "logd.writer"); 41e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn name_set = true; 42e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn } 438daa9af02dc0e63ce220e3fa95bf5fe4d6b7a99aMark Salyzyn 448444eb81b37991ce0fc4ae1d8d79b01688a02426Mark Salyzyn char buffer[sizeof_log_id_t + sizeof(uint16_t) + sizeof(log_time) 45b059cf53c9185702e99345b7319bcb075ffc5beeMark Salyzyn + LOGGER_ENTRY_MAX_PAYLOAD]; 460175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn struct iovec iov = { buffer, sizeof(buffer) }; 470175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn memset(buffer, 0, sizeof(buffer)); 480175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 490175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn char control[CMSG_SPACE(sizeof(struct ucred))]; 500175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn struct msghdr hdr = { 510175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn NULL, 520175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 0, 530175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn &iov, 540175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 1, 550175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn control, 560175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn sizeof(control), 570175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 0, 580175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn }; 590175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 600175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn int socket = cli->getSocket(); 610175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 620175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn ssize_t n = recvmsg(socket, &hdr, 0); 63b5f6e45d6bddd2f6262bf387c3314dc744896320Mark Salyzyn if (n <= (ssize_t)(sizeof(android_log_header_t))) { 640175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return false; 650175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 660175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 670175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn struct ucred *cred = NULL; 680175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 690175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr); 700175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn while (cmsg != NULL) { 710175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (cmsg->cmsg_level == SOL_SOCKET 720175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn && cmsg->cmsg_type == SCM_CREDENTIALS) { 730175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn cred = (struct ucred *)CMSG_DATA(cmsg); 740175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn break; 750175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 760175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn cmsg = CMSG_NXTHDR(&hdr, cmsg); 770175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 780175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 790175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (cred == NULL) { 800175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return false; 810175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 820175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 83e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn if (cred->uid == AID_LOGD) { 840175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // ignore log messages we send to ourself. 850175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // Such log messages are often generated by libraries we depend on 860175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn // which use standard Android logging. 870175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return false; 880175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 890175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 90b5f6e45d6bddd2f6262bf387c3314dc744896320Mark Salyzyn android_log_header_t *header = reinterpret_cast<android_log_header_t *>(buffer); 91a1aacb71f387c91d5fe383b8aaa5b0be2ec9cd3cMark Salyzyn if (/* header->id < LOG_ID_MIN || */ header->id >= LOG_ID_MAX || header->id == LOG_ID_KERNEL) { 920175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return false; 930175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 940175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 95b5f6e45d6bddd2f6262bf387c3314dc744896320Mark Salyzyn char *msg = ((char *)buffer) + sizeof(android_log_header_t); 96b5f6e45d6bddd2f6262bf387c3314dc744896320Mark Salyzyn n -= sizeof(android_log_header_t); 970175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 9822e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn // NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a 9922e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn // truncated message to the logs. 100e0fa291e898b451dc198ed52cebac3ffefac066eMark Salyzyn 101202e153f94a0957185ae4b4bed4c5356513e4322Mark Salyzyn if (logbuf->log((log_id_t)header->id, header->realtime, 102202e153f94a0957185ae4b4bed4c5356513e4322Mark Salyzyn cred->uid, cred->pid, header->tid, msg, 103202e153f94a0957185ae4b4bed4c5356513e4322Mark Salyzyn ((size_t) n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX) >= 0) { 104202e153f94a0957185ae4b4bed4c5356513e4322Mark Salyzyn reader->notifyNewLog(); 105202e153f94a0957185ae4b4bed4c5356513e4322Mark Salyzyn } 1060175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 1070175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return true; 1080175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn} 1090175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 1100175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzynint LogListener::getLogSocket() { 111dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn static const char socketName[] = "logdw"; 112dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn int sock = android_get_control_socket(socketName); 113dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn 114dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn if (sock < 0) { 115dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn sock = socket_local_server(socketName, 116dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn ANDROID_SOCKET_NAMESPACE_RESERVED, 117dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn SOCK_DGRAM); 118dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn } 119dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn 1200175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn int on = 1; 1210175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) { 1220175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return -1; 1230175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 1240175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return sock; 1250175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn} 126