Skip to content

Commit 06e0c70

Browse files
MaxBiresGerrit Code Review
authored and
Gerrit Code Review
committed
Merge "Add a feature to show which bugs are tracking which se denials"
2 parents b1d93a8 + 4214d13 commit 06e0c70

File tree

2 files changed

+120
-32
lines changed

2 files changed

+120
-32
lines changed

logd/LogAudit.cpp

+115-32
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
#include <sys/uio.h>
2626
#include <syslog.h>
2727

28+
#include <fstream>
29+
#include <sstream>
30+
2831
#include <android-base/macros.h>
32+
#include <log/log_properties.h>
2933
#include <private/android_filesystem_config.h>
3034
#include <private/android_logger.h>
3135

@@ -138,6 +142,71 @@ bool LogAudit::onDataAvailable(SocketClient* cli) {
138142
return true;
139143
}
140144

145+
static inline bool hasMetadata(char* str, int str_len) {
146+
// need to check and see if str already contains bug metadata from
147+
// possibility of stuttering if log audit crashes and then reloads kernel
148+
// messages. Kernel denials that contain metadata will either end in
149+
// "b/[0-9]+$" or "b/[0-9]+ duplicate messages suppressed$" which will put
150+
// a '/' character at either 9 or 39 indices away from the end of the str.
151+
return str_len >= 39 &&
152+
(str[str_len - 9] == '/' || str[str_len - 39] == '/');
153+
}
154+
155+
std::map<std::string, std::string> LogAudit::populateDenialMap() {
156+
std::ifstream bug_file("/system/etc/selinux/selinux_denial_metadata");
157+
std::string line;
158+
// allocate a map for the static map pointer in logParse to keep track of,
159+
// this function only runs once
160+
std::map<std::string, std::string> denial_to_bug;
161+
if (bug_file.good()) {
162+
std::string scontext;
163+
std::string tcontext;
164+
std::string tclass;
165+
std::string bug_num;
166+
while (std::getline(bug_file, line)) {
167+
std::stringstream split_line(line);
168+
split_line >> scontext >> tcontext >> tclass >> bug_num;
169+
denial_to_bug.emplace(scontext + tcontext + tclass, bug_num);
170+
}
171+
}
172+
return denial_to_bug;
173+
}
174+
175+
std::string LogAudit::denialParse(const std::string& denial, char terminator,
176+
const std::string& search_term) {
177+
size_t start_index = denial.find(search_term);
178+
if (start_index != std::string::npos) {
179+
start_index += search_term.length();
180+
return denial.substr(
181+
start_index, denial.find(terminator, start_index) - start_index);
182+
}
183+
return "";
184+
}
185+
186+
void LogAudit::logParse(const std::string& string, std::string* bug_num) {
187+
if (!__android_log_is_debuggable()) {
188+
bug_num->assign("");
189+
return;
190+
}
191+
static std::map<std::string, std::string> denial_to_bug =
192+
populateDenialMap();
193+
std::string scontext = denialParse(string, ':', "scontext=u:object_r:");
194+
std::string tcontext = denialParse(string, ':', "tcontext=u:object_r:");
195+
std::string tclass = denialParse(string, ' ', "tclass=");
196+
if (scontext.empty()) {
197+
scontext = denialParse(string, ':', "scontext=u:r:");
198+
}
199+
if (tcontext.empty()) {
200+
tcontext = denialParse(string, ':', "tcontext=u:r:");
201+
}
202+
auto search = denial_to_bug.find(scontext + tcontext + tclass);
203+
if (search != denial_to_bug.end()) {
204+
bug_num->assign(" b/" + search->second);
205+
} else {
206+
bug_num->assign("");
207+
}
208+
}
209+
141210
int LogAudit::logPrint(const char* fmt, ...) {
142211
if (fmt == NULL) {
143212
return -EINVAL;
@@ -153,7 +222,6 @@ int LogAudit::logPrint(const char* fmt, ...) {
153222
if (rc < 0) {
154223
return rc;
155224
}
156-
157225
char* cp;
158226
// Work around kernels missing
159227
// https://github.com/torvalds/linux/commit/b8f89caafeb55fba75b74bea25adc4e4cd91be67
@@ -165,10 +233,10 @@ int LogAudit::logPrint(const char* fmt, ...) {
165233
while ((cp = strstr(str, " "))) {
166234
memmove(cp, cp + 1, strlen(cp + 1) + 1);
167235
}
168-
169236
bool info = strstr(str, " permissive=1") || strstr(str, " policy loaded ");
237+
static std::string bug_metadata;
170238
if ((fdDmesg >= 0) && initialized) {
171-
struct iovec iov[3];
239+
struct iovec iov[4];
172240
static const char log_info[] = { KMSG_PRIORITY(LOG_INFO) };
173241
static const char log_warning[] = { KMSG_PRIORITY(LOG_WARNING) };
174242
static const char newline[] = "\n";
@@ -197,19 +265,20 @@ int LogAudit::logPrint(const char* fmt, ...) {
197265
}
198266
if (!skip) {
199267
static const char resume[] = " duplicate messages suppressed\n";
200-
201268
iov[0].iov_base = last_info ? const_cast<char*>(log_info)
202269
: const_cast<char*>(log_warning);
203270
iov[0].iov_len =
204271
last_info ? sizeof(log_info) : sizeof(log_warning);
205272
iov[1].iov_base = last_str;
206273
iov[1].iov_len = strlen(last_str);
274+
iov[2].iov_base = const_cast<char*>(bug_metadata.c_str());
275+
iov[2].iov_len = bug_metadata.length();
207276
if (count > 1) {
208-
iov[2].iov_base = const_cast<char*>(resume);
209-
iov[2].iov_len = strlen(resume);
277+
iov[3].iov_base = const_cast<char*>(resume);
278+
iov[3].iov_len = strlen(resume);
210279
} else {
211-
iov[2].iov_base = const_cast<char*>(newline);
212-
iov[2].iov_len = strlen(newline);
280+
iov[3].iov_base = const_cast<char*>(newline);
281+
iov[3].iov_len = strlen(newline);
213282
}
214283

215284
writev(fdDmesg, iov, arraysize(iov));
@@ -223,13 +292,16 @@ int LogAudit::logPrint(const char* fmt, ...) {
223292
last_info = info;
224293
}
225294
if (count == 0) {
295+
logParse(str, &bug_metadata);
226296
iov[0].iov_base = info ? const_cast<char*>(log_info)
227297
: const_cast<char*>(log_warning);
228298
iov[0].iov_len = info ? sizeof(log_info) : sizeof(log_warning);
229299
iov[1].iov_base = str;
230300
iov[1].iov_len = strlen(str);
231-
iov[2].iov_base = const_cast<char*>(newline);
232-
iov[2].iov_len = strlen(newline);
301+
iov[2].iov_base = const_cast<char*>(bug_metadata.c_str());
302+
iov[2].iov_len = bug_metadata.length();
303+
iov[3].iov_base = const_cast<char*>(newline);
304+
iov[3].iov_len = strlen(newline);
233305

234306
writev(fdDmesg, iov, arraysize(iov));
235307
}
@@ -285,24 +357,32 @@ int LogAudit::logPrint(const char* fmt, ...) {
285357

286358
// log to events
287359

288-
size_t l = strnlen(str, LOGGER_ENTRY_MAX_PAYLOAD);
289-
size_t n = l + sizeof(android_log_event_string_t);
360+
size_t str_len = strnlen(str, LOGGER_ENTRY_MAX_PAYLOAD);
361+
if (((fdDmesg < 0) || !initialized) && !hasMetadata(str, str_len))
362+
logParse(str, &bug_metadata);
363+
str_len = (str_len + bug_metadata.length() <= LOGGER_ENTRY_MAX_PAYLOAD)
364+
? str_len + bug_metadata.length()
365+
: LOGGER_ENTRY_MAX_PAYLOAD;
366+
size_t message_len = str_len + sizeof(android_log_event_string_t);
290367

291368
bool notify = false;
292369

293370
if (events) { // begin scope for event buffer
294-
uint32_t buffer[(n + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
371+
uint32_t buffer[(message_len + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
295372

296373
android_log_event_string_t* event =
297374
reinterpret_cast<android_log_event_string_t*>(buffer);
298375
event->header.tag = htole32(AUDITD_LOG_TAG);
299376
event->type = EVENT_TYPE_STRING;
300-
event->length = htole32(l);
301-
memcpy(event->data, str, l);
302-
303-
rc = logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid,
304-
reinterpret_cast<char*>(event),
305-
(n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX);
377+
event->length = htole32(message_len);
378+
memcpy(event->data, str, str_len - bug_metadata.length());
379+
memcpy(event->data + str_len - bug_metadata.length(),
380+
bug_metadata.c_str(), bug_metadata.length());
381+
382+
rc = logbuf->log(
383+
LOG_ID_EVENTS, now, uid, pid, tid, reinterpret_cast<char*>(event),
384+
(message_len <= USHRT_MAX) ? (unsigned short)message_len
385+
: USHRT_MAX);
306386
if (rc >= 0) {
307387
notify = true;
308388
}
@@ -333,28 +413,31 @@ int LogAudit::logPrint(const char* fmt, ...) {
333413
const char* ecomm = strchr(comm, '"');
334414
if (ecomm) {
335415
++ecomm;
336-
l = ecomm - comm;
416+
str_len = ecomm - comm;
337417
} else {
338-
l = strlen(comm) + 1;
418+
str_len = strlen(comm) + 1;
339419
ecomm = "";
340420
}
341-
size_t b = estr - str;
342-
if (b > LOGGER_ENTRY_MAX_PAYLOAD) {
343-
b = LOGGER_ENTRY_MAX_PAYLOAD;
421+
size_t prefix_len = estr - str;
422+
if (prefix_len > LOGGER_ENTRY_MAX_PAYLOAD) {
423+
prefix_len = LOGGER_ENTRY_MAX_PAYLOAD;
344424
}
345-
size_t e = strnlen(ecomm, LOGGER_ENTRY_MAX_PAYLOAD - b);
346-
n = b + e + l + 2;
425+
size_t suffix_len = strnlen(ecomm, LOGGER_ENTRY_MAX_PAYLOAD - prefix_len);
426+
message_len = str_len + prefix_len + suffix_len + bug_metadata.length() + 2;
347427

348428
if (main) { // begin scope for main buffer
349-
char newstr[n];
429+
char newstr[message_len];
350430

351431
*newstr = info ? ANDROID_LOG_INFO : ANDROID_LOG_WARN;
352-
strlcpy(newstr + 1, comm, l);
353-
strncpy(newstr + 1 + l, str, b);
354-
strncpy(newstr + 1 + l + b, ecomm, e);
432+
strlcpy(newstr + 1, comm, str_len);
433+
strncpy(newstr + 1 + str_len, str, prefix_len);
434+
strncpy(newstr + 1 + str_len + prefix_len, ecomm, suffix_len);
435+
strncpy(newstr + 1 + str_len + prefix_len + suffix_len,
436+
bug_metadata.c_str(), bug_metadata.length());
355437

356438
rc = logbuf->log(LOG_ID_MAIN, now, uid, pid, tid, newstr,
357-
(n <= USHRT_MAX) ? (unsigned short)n : USHRT_MAX);
439+
(message_len <= USHRT_MAX) ? (unsigned short)message_len
440+
: USHRT_MAX);
358441

359442
if (rc >= 0) {
360443
notify = true;
@@ -368,7 +451,7 @@ int LogAudit::logPrint(const char* fmt, ...) {
368451
if (notify) {
369452
reader->notifyNewLog();
370453
if (rc < 0) {
371-
rc = n;
454+
rc = message_len;
372455
}
373456
}
374457

logd/LogAudit.h

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef _LOGD_LOG_AUDIT_H__
1818
#define _LOGD_LOG_AUDIT_H__
1919

20+
#include <map>
2021
#include <queue>
2122

2223
#include <sysutils/SocketListener.h>
@@ -50,6 +51,10 @@ class LogAudit : public SocketListener {
5051

5152
private:
5253
static int getLogSocket();
54+
std::map<std::string, std::string> populateDenialMap();
55+
std::string denialParse(const std::string& denial, char terminator,
56+
const std::string& search_term);
57+
void logParse(const std::string& string, std::string* bug_num);
5358
int logPrint(const char* fmt, ...)
5459
__attribute__((__format__(__printf__, 2, 3)));
5560
};

0 commit comments

Comments
 (0)