diff options
author | Mark Salyzyn | 2015-12-04 12:59:45 -0600 |
---|---|---|
committer | Mark Salyzyn | 2015-12-08 18:46:29 -0600 |
commit | 083b037c0740ca00f72429e4457bfdd4b4d4dfa7 (patch) | |
tree | 6748f9f8bcaebd495df77604dfeba68e0b65b5be /logd | |
parent | cb3e6ef15459388fc8fee2b4a3157ff0eac0714a (diff) | |
download | platform-system-core-083b037c0740ca00f72429e4457bfdd4b4d4dfa7.tar.gz platform-system-core-083b037c0740ca00f72429e4457bfdd4b4d4dfa7.tar.xz platform-system-core-083b037c0740ca00f72429e4457bfdd4b4d4dfa7.zip |
logd: liblog: logcat: Add LOG_ID_SECURITY
- Largish commit, buffer and access controls done together
- Add LOG_ID_SECURITY binary content log
- Add "default" meta buffer
- allow LOG_ID_SECURITY only from AID_SYSTEM and AID_ROOT UID & GID
- Use __android_log_security() to gate logging
- Add __android_log_security_bwrite() native access to security
logging.
- Add liblog.__security_buffer end-to-end gTest
Bug: 26029733
Change-Id: Ibcf5b4660c17c1aa6902c0d93f8ffd29c93d9a93
Diffstat (limited to 'logd')
-rw-r--r-- | logd/CommandListener.cpp | 1 | ||||
-rw-r--r-- | logd/FlushCommand.cpp | 1 | ||||
-rw-r--r-- | logd/LogBuffer.cpp | 38 | ||||
-rw-r--r-- | logd/LogBufferElement.cpp | 9 | ||||
-rw-r--r-- | logd/LogCommand.cpp | 13 | ||||
-rw-r--r-- | logd/LogCommand.h | 2 | ||||
-rw-r--r-- | logd/LogListener.cpp | 7 | ||||
-rw-r--r-- | logd/LogStatistics.cpp | 17 | ||||
-rw-r--r-- | logd/LogStatistics.h | 3 | ||||
-rw-r--r-- | logd/LogUtils.h | 7 |
10 files changed, 67 insertions, 31 deletions
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp index c45111aa5..e10335916 100644 --- a/logd/CommandListener.cpp +++ b/logd/CommandListener.cpp | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include "CommandListener.h" | 35 | #include "CommandListener.h" |
36 | #include "LogCommand.h" | 36 | #include "LogCommand.h" |
37 | #include "LogUtils.h" | ||
37 | 38 | ||
38 | CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/, | 39 | CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/, |
39 | LogListener * /*swl*/) : | 40 | LogListener * /*swl*/) : |
diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp index bf650cdaa..cb3d1c278 100644 --- a/logd/FlushCommand.cpp +++ b/logd/FlushCommand.cpp | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "LogCommand.h" | 21 | #include "LogCommand.h" |
22 | #include "LogReader.h" | 22 | #include "LogReader.h" |
23 | #include "LogTimes.h" | 23 | #include "LogTimes.h" |
24 | #include "LogUtils.h" | ||
24 | 25 | ||
25 | FlushCommand::FlushCommand(LogReader &reader, | 26 | FlushCommand::FlushCommand(LogReader &reader, |
26 | bool nonBlock, | 27 | bool nonBlock, |
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index 6770bb7f2..3ce6b61e0 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp | |||
@@ -199,22 +199,24 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, | |||
199 | 199 | ||
200 | LogBufferElement *elem = new LogBufferElement(log_id, realtime, | 200 | LogBufferElement *elem = new LogBufferElement(log_id, realtime, |
201 | uid, pid, tid, msg, len); | 201 | uid, pid, tid, msg, len); |
202 | int prio = ANDROID_LOG_INFO; | 202 | if (log_id != LOG_ID_SECURITY) { |
203 | const char *tag = NULL; | 203 | int prio = ANDROID_LOG_INFO; |
204 | if (log_id == LOG_ID_EVENTS) { | 204 | const char *tag = NULL; |
205 | tag = android::tagToName(elem->getTag()); | 205 | if (log_id == LOG_ID_EVENTS) { |
206 | } else { | 206 | tag = android::tagToName(elem->getTag()); |
207 | prio = *msg; | 207 | } else { |
208 | tag = msg + 1; | 208 | prio = *msg; |
209 | } | 209 | tag = msg + 1; |
210 | if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) { | 210 | } |
211 | // Log traffic received to total | 211 | if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) { |
212 | pthread_mutex_lock(&mLogElementsLock); | 212 | // Log traffic received to total |
213 | stats.add(elem); | 213 | pthread_mutex_lock(&mLogElementsLock); |
214 | stats.subtract(elem); | 214 | stats.add(elem); |
215 | pthread_mutex_unlock(&mLogElementsLock); | 215 | stats.subtract(elem); |
216 | delete elem; | 216 | pthread_mutex_unlock(&mLogElementsLock); |
217 | return -EACCES; | 217 | delete elem; |
218 | return -EACCES; | ||
219 | } | ||
218 | } | 220 | } |
219 | 221 | ||
220 | pthread_mutex_lock(&mLogElementsLock); | 222 | pthread_mutex_lock(&mLogElementsLock); |
@@ -484,7 +486,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
484 | } | 486 | } |
485 | 487 | ||
486 | // prune by worst offender by uid | 488 | // prune by worst offender by uid |
487 | bool hasBlacklist = mPrune.naughty(); | 489 | bool hasBlacklist = (id != LOG_ID_SECURITY) && mPrune.naughty(); |
488 | while (!clearAll && (pruneRows > 0)) { | 490 | while (!clearAll && (pruneRows > 0)) { |
489 | // recalculate the worst offender on every batched pass | 491 | // recalculate the worst offender on every batched pass |
490 | uid_t worst = (uid_t) -1; | 492 | uid_t worst = (uid_t) -1; |
@@ -654,7 +656,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { | |||
654 | } | 656 | } |
655 | 657 | ||
656 | bool whitelist = false; | 658 | bool whitelist = false; |
657 | bool hasWhitelist = mPrune.nice() && !clearAll; | 659 | bool hasWhitelist = (id != LOG_ID_SECURITY) && mPrune.nice() && !clearAll; |
658 | it = mLogElements.begin(); | 660 | it = mLogElements.begin(); |
659 | while((pruneRows > 0) && (it != mLogElements.end())) { | 661 | while((pruneRows > 0) && (it != mLogElements.end())) { |
660 | LogBufferElement *e = *it; | 662 | LogBufferElement *e = *it; |
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp index c4c302b0a..f92a085cb 100644 --- a/logd/LogBufferElement.cpp +++ b/logd/LogBufferElement.cpp | |||
@@ -51,7 +51,8 @@ LogBufferElement::~LogBufferElement() { | |||
51 | } | 51 | } |
52 | 52 | ||
53 | uint32_t LogBufferElement::getTag() const { | 53 | uint32_t LogBufferElement::getTag() const { |
54 | if ((mLogId != LOG_ID_EVENTS) || !mMsg || (mMsgLen < sizeof(uint32_t))) { | 54 | if (((mLogId != LOG_ID_EVENTS) && (mLogId != LOG_ID_SECURITY)) || |
55 | !mMsg || (mMsgLen < sizeof(uint32_t))) { | ||
55 | return 0; | 56 | return 0; |
56 | } | 57 | } |
57 | return le32toh(reinterpret_cast<android_event_header_t *>(mMsg)->tag); | 58 | return le32toh(reinterpret_cast<android_event_header_t *>(mMsg)->tag); |
@@ -158,7 +159,9 @@ size_t LogBufferElement::populateDroppedMessage(char *&buffer, | |||
158 | mDropped, (mDropped > 1) ? "s" : ""); | 159 | mDropped, (mDropped > 1) ? "s" : ""); |
159 | 160 | ||
160 | size_t hdrLen; | 161 | size_t hdrLen; |
161 | if (mLogId == LOG_ID_EVENTS) { | 162 | // LOG_ID_SECURITY not strictly needed since spam filter not activated, |
163 | // but required for accuracy. | ||
164 | if ((mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY)) { | ||
162 | hdrLen = sizeof(android_log_event_string_t); | 165 | hdrLen = sizeof(android_log_event_string_t); |
163 | } else { | 166 | } else { |
164 | hdrLen = 1 + sizeof(tag); | 167 | hdrLen = 1 + sizeof(tag); |
@@ -172,7 +175,7 @@ size_t LogBufferElement::populateDroppedMessage(char *&buffer, | |||
172 | } | 175 | } |
173 | 176 | ||
174 | size_t retval = hdrLen + len; | 177 | size_t retval = hdrLen + len; |
175 | if (mLogId == LOG_ID_EVENTS) { | 178 | if ((mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY)) { |
176 | android_log_event_string_t *event = | 179 | android_log_event_string_t *event = |
177 | reinterpret_cast<android_log_event_string_t *>(buffer); | 180 | reinterpret_cast<android_log_event_string_t *>(buffer); |
178 | 181 | ||
diff --git a/logd/LogCommand.cpp b/logd/LogCommand.cpp index 6d0e92e4e..3b1757656 100644 --- a/logd/LogCommand.cpp +++ b/logd/LogCommand.cpp | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <private/android_filesystem_config.h> | 22 | #include <private/android_filesystem_config.h> |
23 | 23 | ||
24 | #include "LogCommand.h" | 24 | #include "LogCommand.h" |
25 | #include "LogUtils.h" | ||
25 | 26 | ||
26 | LogCommand::LogCommand(const char *cmd) : FrameworkCommand(cmd) { | 27 | LogCommand::LogCommand(const char *cmd) : FrameworkCommand(cmd) { |
27 | } | 28 | } |
@@ -56,20 +57,18 @@ static bool groupIsLog(char *buf) { | |||
56 | return false; | 57 | return false; |
57 | } | 58 | } |
58 | 59 | ||
59 | bool clientHasLogCredentials(SocketClient * cli) { | 60 | bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid) { |
60 | uid_t uid = cli->getUid(); | 61 | if ((uid == AID_ROOT) || (uid == AID_SYSTEM) || (uid == AID_LOG)) { |
61 | if (uid == AID_ROOT) { | ||
62 | return true; | 62 | return true; |
63 | } | 63 | } |
64 | 64 | ||
65 | gid_t gid = cli->getGid(); | ||
66 | if ((gid == AID_ROOT) || (gid == AID_SYSTEM) || (gid == AID_LOG)) { | 65 | if ((gid == AID_ROOT) || (gid == AID_SYSTEM) || (gid == AID_LOG)) { |
67 | return true; | 66 | return true; |
68 | } | 67 | } |
69 | 68 | ||
70 | // FYI We will typically be here for 'adb logcat' | 69 | // FYI We will typically be here for 'adb logcat' |
71 | char filename[256]; | 70 | char filename[256]; |
72 | snprintf(filename, sizeof(filename), "/proc/%u/status", cli->getPid()); | 71 | snprintf(filename, sizeof(filename), "/proc/%u/status", pid); |
73 | 72 | ||
74 | bool ret; | 73 | bool ret; |
75 | bool foundLog = false; | 74 | bool foundLog = false; |
@@ -145,3 +144,7 @@ bool clientHasLogCredentials(SocketClient * cli) { | |||
145 | 144 | ||
146 | return ret; | 145 | return ret; |
147 | } | 146 | } |
147 | |||
148 | bool clientHasLogCredentials(SocketClient *cli) { | ||
149 | return clientHasLogCredentials(cli->getUid(), cli->getGid(), cli->getPid()); | ||
150 | } | ||
diff --git a/logd/LogCommand.h b/logd/LogCommand.h index e3b96a2b7..c944478f8 100644 --- a/logd/LogCommand.h +++ b/logd/LogCommand.h | |||
@@ -26,6 +26,4 @@ public: | |||
26 | virtual ~LogCommand() {} | 26 | virtual ~LogCommand() {} |
27 | }; | 27 | }; |
28 | 28 | ||
29 | bool clientHasLogCredentials(SocketClient * cli); | ||
30 | |||
31 | #endif | 29 | #endif |
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp index b29f5ab92..9bbf9e84b 100644 --- a/logd/LogListener.cpp +++ b/logd/LogListener.cpp | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <private/android_logger.h> | 27 | #include <private/android_logger.h> |
28 | 28 | ||
29 | #include "LogListener.h" | 29 | #include "LogListener.h" |
30 | #include "LogUtils.h" | ||
30 | 31 | ||
31 | LogListener::LogListener(LogBuffer *buf, LogReader *reader) : | 32 | LogListener::LogListener(LogBuffer *buf, LogReader *reader) : |
32 | SocketListener(getLogSocket(), false), | 33 | SocketListener(getLogSocket(), false), |
@@ -92,6 +93,12 @@ bool LogListener::onDataAvailable(SocketClient *cli) { | |||
92 | return false; | 93 | return false; |
93 | } | 94 | } |
94 | 95 | ||
96 | if ((header->id == LOG_ID_SECURITY) && | ||
97 | (!__android_log_security() || | ||
98 | !clientHasLogCredentials(cred->uid, cred->gid, cred->pid))) { | ||
99 | return false; | ||
100 | } | ||
101 | |||
95 | char *msg = ((char *)buffer) + sizeof(android_log_header_t); | 102 | char *msg = ((char *)buffer) + sizeof(android_log_header_t); |
96 | n -= sizeof(android_log_header_t); | 103 | n -= sizeof(android_log_header_t); |
97 | 104 | ||
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp index 416edd8a1..bf0e30b09 100644 --- a/logd/LogStatistics.cpp +++ b/logd/LogStatistics.cpp | |||
@@ -85,7 +85,11 @@ void LogStatistics::add(LogBufferElement *element) { | |||
85 | 85 | ||
86 | uint32_t tag = element->getTag(); | 86 | uint32_t tag = element->getTag(); |
87 | if (tag) { | 87 | if (tag) { |
88 | tagTable.add(tag, element); | 88 | if (log_id == LOG_ID_SECURITY) { |
89 | securityTagTable.add(tag, element); | ||
90 | } else { | ||
91 | tagTable.add(tag, element); | ||
92 | } | ||
89 | } | 93 | } |
90 | } | 94 | } |
91 | 95 | ||
@@ -113,7 +117,11 @@ void LogStatistics::subtract(LogBufferElement *element) { | |||
113 | 117 | ||
114 | uint32_t tag = element->getTag(); | 118 | uint32_t tag = element->getTag(); |
115 | if (tag) { | 119 | if (tag) { |
116 | tagTable.subtract(tag, element); | 120 | if (log_id == LOG_ID_SECURITY) { |
121 | securityTagTable.subtract(tag, element); | ||
122 | } else { | ||
123 | tagTable.subtract(tag, element); | ||
124 | } | ||
117 | } | 125 | } |
118 | } | 126 | } |
119 | 127 | ||
@@ -468,6 +476,11 @@ std::string LogStatistics::format(uid_t uid, unsigned int logMask) const { | |||
468 | output += tagTable.format(*this, uid, name, LOG_ID_EVENTS); | 476 | output += tagTable.format(*this, uid, name, LOG_ID_EVENTS); |
469 | } | 477 | } |
470 | 478 | ||
479 | if (enable && (logMask & (1 << LOG_ID_SECURITY))) { | ||
480 | name = "Chattiest security log buffer TAGs:"; | ||
481 | output += securityTagTable.format(*this, uid, name, LOG_ID_SECURITY); | ||
482 | } | ||
483 | |||
471 | return output; | 484 | return output; |
472 | } | 485 | } |
473 | 486 | ||
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h index 28810d9d5..8558b0671 100644 --- a/logd/LogStatistics.h +++ b/logd/LogStatistics.h | |||
@@ -397,6 +397,9 @@ class LogStatistics { | |||
397 | typedef LogHashtable<uint32_t, TagEntry> tagTable_t; | 397 | typedef LogHashtable<uint32_t, TagEntry> tagTable_t; |
398 | tagTable_t tagTable; | 398 | tagTable_t tagTable; |
399 | 399 | ||
400 | // security tag list | ||
401 | tagTable_t securityTagTable; | ||
402 | |||
400 | public: | 403 | public: |
401 | LogStatistics(); | 404 | LogStatistics(); |
402 | 405 | ||
diff --git a/logd/LogUtils.h b/logd/LogUtils.h index 533eb1c5f..b591f2892 100644 --- a/logd/LogUtils.h +++ b/logd/LogUtils.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <sys/types.h> | 20 | #include <sys/types.h> |
21 | 21 | ||
22 | #include <log/log.h> | 22 | #include <log/log.h> |
23 | #include <sysutils/SocketClient.h> | ||
23 | 24 | ||
24 | // Hijack this header as a common include file used by most all sources | 25 | // Hijack this header as a common include file used by most all sources |
25 | // to report some utilities defined here and there. | 26 | // to report some utilities defined here and there. |
@@ -38,8 +39,12 @@ const char *tagToName(uint32_t tag); | |||
38 | 39 | ||
39 | } | 40 | } |
40 | 41 | ||
42 | // Furnished in LogCommand.cpp | ||
43 | bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid); | ||
44 | bool clientHasLogCredentials(SocketClient *cli); | ||
45 | |||
41 | static inline bool worstUidEnabledForLogid(log_id_t id) { | 46 | static inline bool worstUidEnabledForLogid(log_id_t id) { |
42 | return (id != LOG_ID_CRASH) && (id != LOG_ID_KERNEL) && (id != LOG_ID_EVENTS); | 47 | return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) || (id == LOG_ID_RADIO); |
43 | } | 48 | } |
44 | 49 | ||
45 | template <int (*cmp)(const char *l, const char *r, const size_t s)> | 50 | template <int (*cmp)(const char *l, const char *r, const size_t s)> |