Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8913dec5 authored by Mark Salyzyn's avatar Mark Salyzyn Committed by Gerrit Code Review
Browse files

Merge changes Iddd45a67,Ifdc20b09,Ibc68480d

* changes:
  logd: disable worst uid prune for events buffer
  Revert: "logd: default off by-UID spam filter"
  logd: annotate worst-UID pruned entries
parents 9b83b623 ae769238
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -32,8 +32,9 @@ LOCAL_SHARED_LIBRARIES := \
#        "s/^\([0-9]*\)[ \t]*$1[ \t].*/-D`echo $1 | tr a-z A-Z`_LOG_TAG=\1/p" \
#        $(LOCAL_PATH)/$2/event.logtags)
#  event_flag := $(call event_logtags,auditd)
#  event_flag += $(call event_logtags,logd)
# so make sure we do not regret hard-coding it as follows:
event_flag := -DAUDITD_LOG_TAG=1003
event_flag := -DAUDITD_LOG_TAG=1003 -DLOGD_LOG_TAG=1004

LOCAL_CFLAGS := -Werror $(event_flag)

+73 −10
Original line number Diff line number Diff line
@@ -279,7 +279,7 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
        size_t worst_sizes = 0;
        size_t second_worst_sizes = 0;

        if ((id != LOG_ID_CRASH) && mPrune.worstUidEnabled()) {
        if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) {
            std::unique_ptr<const UidEntry *[]> sorted = stats.sort(2, id);

            if (sorted.get()) {
@@ -297,6 +297,8 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
        }

        bool kick = false;
        bool leading = true;
        LogBufferElement *last = NULL;
        for(it = mLogElements.begin(); it != mLogElements.end();) {
            LogBufferElement *e = *it;

@@ -309,26 +311,87 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
                continue;
            }

            uid_t uid = e->getUid();
            unsigned short dropped = e->getDropped();

            // !Worst and !BlackListed?
            if ((uid != worst) && (!hasBlacklist || !mPrune.naughty(e))) {
                ++it;
            // remove any leading drops
            if (leading && dropped) {
                it = erase(it);
                continue;
            }

            unsigned short len = e->getMsgLen();
            pid_t pid = e->getPid();

            // merge any drops
            if (last && dropped
             && ((dropped + last->getDropped()) < USHRT_MAX)
             && (last->getPid() == pid)
             && (last->getTid() == e->getTid())) {
                it = mLogElements.erase(it);
                stats.erase(e);
                delete e;
                last->setDropped(dropped + last->getDropped());
                continue;
            }

            leading = false;

            if (hasBlacklist && mPrune.naughty(e)) {
                last = NULL;
                it = erase(it);
                if (dropped) {
                    continue;
                }

                pruneRows--;
                if (pruneRows == 0) {
                    break;
                }

            if (uid != worst) {
                if (e->getUid() == worst) {
                    kick = true;
                    if (worst_sizes < second_worst_sizes) {
                        break;
                    }
                    worst_sizes -= e->getMsgLen();
                }
                continue;
            }

            if (dropped) {
                last = e;
                ++it;
                continue;
            }

            if (e->getUid() != worst) {
                last = NULL;
                ++it;
                continue;
            }

            pruneRows--;
            if (pruneRows == 0) {
                break;
            }

            kick = true;

            unsigned short len = e->getMsgLen();
            stats.drop(e);
            e->setDropped(1);
            // merge any drops
            if (last
             && (last->getDropped() < (USHRT_MAX - 1))
             && (last->getPid() == pid)
             && (last->getTid() == e->getTid())) {
                it = mLogElements.erase(it);
                stats.erase(e);
                delete e;
                last->setDropped(last->getDropped() + 1);
            } else {
                last = e;
                ++it;
            }
            if (worst_sizes < second_worst_sizes) {
                break;
            }
+72 −6
Original line number Diff line number Diff line
@@ -14,14 +14,17 @@
 * limitations under the License.
 */

#include <endian.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <log/logger.h>
#include <private/android_logger.h>

#include "LogBufferElement.h"
#include "LogCommand.h"
#include "LogReader.h"

const uint64_t LogBufferElement::FLUSH_ERROR(0);
@@ -45,11 +48,59 @@ LogBufferElement::~LogBufferElement() {
    delete [] mMsg;
}

// assumption: mMsg == NULL
size_t LogBufferElement::populateDroppedMessage(char *&buffer, bool privileged) {
    static const char format_uid[] = "uid=%u dropped=%u";
    static const size_t unprivileged_offset = 7;
    static const char tag[] = "logd";

    size_t len;
    if (privileged) {
        len = snprintf(NULL, 0, format_uid, mUid, mDropped);
    } else {
        len = snprintf(NULL, 0, format_uid + unprivileged_offset, mDropped);
    }

    size_t hdrLen;
    if (mLogId == LOG_ID_EVENTS) {
        hdrLen = sizeof(android_log_event_string_t);
    } else {
        hdrLen = 1 + sizeof(tag);
    }

    buffer = static_cast<char *>(calloc(1, hdrLen + len + 1));
    if (!buffer) {
        return 0;
    }

    size_t retval = hdrLen + len;
    if (mLogId == LOG_ID_EVENTS) {
        android_log_event_string_t *e = reinterpret_cast<android_log_event_string_t *>(buffer);

        e->header.tag = htole32(LOGD_LOG_TAG);
        e->type = EVENT_TYPE_STRING;
        e->length = htole32(len);
    } else {
        ++retval;
        buffer[0] = ANDROID_LOG_INFO;
        strcpy(buffer + 1, tag);
    }

    if (privileged) {
        snprintf(buffer + hdrLen, len + 1, format_uid, mUid, mDropped);
    } else {
        snprintf(buffer + hdrLen, len + 1, format_uid + unprivileged_offset, mDropped);
    }

    return retval;
}

uint64_t LogBufferElement::flushTo(SocketClient *reader) {
    struct logger_entry_v3 entry;

    memset(&entry, 0, sizeof(struct logger_entry_v3));

    entry.hdr_size = sizeof(struct logger_entry_v3);
    entry.len = mMsgLen;
    entry.lid = mLogId;
    entry.pid = mPid;
    entry.tid = mTid;
@@ -59,11 +110,26 @@ uint64_t LogBufferElement::flushTo(SocketClient *reader) {
    struct iovec iovec[2];
    iovec[0].iov_base = &entry;
    iovec[0].iov_len = sizeof(struct logger_entry_v3);

    char *buffer = NULL;

    if (!mMsg) {
        entry.len = populateDroppedMessage(buffer, clientHasLogCredentials(reader));
        if (!entry.len) {
            return mSequence;
        }
        iovec[1].iov_base = buffer;
    } else {
        entry.len = mMsgLen;
        iovec[1].iov_base = mMsg;
    iovec[1].iov_len = mMsgLen;
    if (reader->sendDatav(iovec, 2)) {
        return FLUSH_ERROR;
    }
    iovec[1].iov_len = entry.len;

    return mSequence;
    uint64_t retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mSequence;

    if (buffer) {
        free(buffer);
    }

    return retval;
}
+21 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define _LOGD_LOG_BUFFER_ELEMENT_H__

#include <stdatomic.h>
#include <stdlib.h>
#include <sys/types.h>

#include <sysutils/SocketClient.h>
@@ -32,17 +33,27 @@ char *uidToName(uid_t uid);

}

static inline bool worstUidEnabledForLogid(log_id_t id) {
    return (id != LOG_ID_CRASH) && (id != LOG_ID_EVENTS);
}

class LogBufferElement {
    const log_id_t mLogId;
    const uid_t mUid;
    const pid_t mPid;
    const pid_t mTid;
    char *mMsg;
    const unsigned short mMsgLen;
    union {
        const unsigned short mMsgLen; // mMSg != NULL
        unsigned short mDropped;      // mMsg == NULL
    };
    const uint64_t mSequence;
    const log_time mRealTime;
    static atomic_int_fast64_t sequence;

    // assumption: mMsg == NULL
    size_t populateDroppedMessage(char *&buffer, bool privileged);

public:
    LogBufferElement(log_id_t log_id, log_time realtime,
                     uid_t uid, pid_t pid, pid_t tid,
@@ -53,7 +64,15 @@ public:
    uid_t getUid(void) const { return mUid; }
    pid_t getPid(void) const { return mPid; }
    pid_t getTid(void) const { return mTid; }
    unsigned short getMsgLen() const { return mMsgLen; }
    unsigned short getDropped(void) const { return mMsg ? 0 : mDropped; }
    unsigned short setDropped(unsigned short value) {
        if (mMsg) {
            free(mMsg);
            mMsg = NULL;
        }
        return mDropped = value;
    }
    unsigned short getMsgLen() const { return mMsg ? mMsgLen : 0; }
    uint64_t getSequence(void) const { return mSequence; }
    static uint64_t getCurrentSequence(void) { return sequence.load(memory_order_relaxed); }
    log_time getRealTime(void) const { return mRealTime; }
+78 −14
Original line number Diff line number Diff line
@@ -71,16 +71,19 @@ void LogStatistics::add(LogBufferElement *e) {
    ++mElements[log_id];

    uid_t uid = e->getUid();
    unsigned short dropped = e->getDropped();
    android::hash_t hash = android::hash_type(uid);
    uidTable_t &table = uidTable[log_id];
    ssize_t index = table.find(-1, hash, uid);
    if (index == -1) {
        UidEntry initEntry(uid);
        initEntry.add(size);
        initEntry.add_dropped(dropped);
        table.add(hash, initEntry);
    } else {
        UidEntry &entry = table.editEntryAt(index);
        entry.add(size);
        entry.add_dropped(dropped);
    }

    mSizesTotal[log_id] += size;
@@ -96,6 +99,7 @@ void LogStatistics::add(LogBufferElement *e) {
    if (index == -1) {
        PidEntry initEntry(pid, uid, android::pidToName(pid));
        initEntry.add(size);
        initEntry.add_dropped(dropped);
        pidTable.add(hash, initEntry);
    } else {
        PidEntry &entry = pidTable.editEntryAt(index);
@@ -109,6 +113,7 @@ void LogStatistics::add(LogBufferElement *e) {
            }
        }
        entry.add(size);
        entry.add_dropped(dropped);
    }
}

@@ -119,12 +124,13 @@ void LogStatistics::subtract(LogBufferElement *e) {
    --mElements[log_id];

    uid_t uid = e->getUid();
    unsigned short dropped = e->getDropped();
    android::hash_t hash = android::hash_type(uid);
    uidTable_t &table = uidTable[log_id];
    ssize_t index = table.find(-1, hash, uid);
    if (index != -1) {
        UidEntry &entry = table.editEntryAt(index);
        if (entry.subtract(size)) {
        if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
            table.removeAt(index);
        }
    }
@@ -138,12 +144,43 @@ void LogStatistics::subtract(LogBufferElement *e) {
    index = pidTable.find(-1, hash, pid);
    if (index != -1) {
        PidEntry &entry = pidTable.editEntryAt(index);
        if (entry.subtract(size)) {
        if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
            pidTable.removeAt(index);
        }
    }
}

// Atomically set an entry to drop
// entry->setDropped(1) must follow this call, caller should do this explicitly.
void LogStatistics::drop(LogBufferElement *e) {
    log_id_t log_id = e->getLogId();
    unsigned short size = e->getMsgLen();
    mSizes[log_id] -= size;

    uid_t uid = e->getUid();
    android::hash_t hash = android::hash_type(uid);
    typeof uidTable[0] &table = uidTable[log_id];
    ssize_t index = table.find(-1, hash, uid);
    if (index != -1) {
        UidEntry &entry = table.editEntryAt(index);
        entry.subtract(size);
        entry.add_dropped(1);
    }

    if (!enable) {
        return;
    }

    pid_t pid = e->getPid();
    hash = android::hash_type(pid);
    index = pidTable.find(-1, hash, pid);
    if (index != -1) {
        PidEntry &entry = pidTable.editEntryAt(index);
        entry.subtract(size);
        entry.add_dropped(1);
    }
}

// caller must own and free character string
char *LogStatistics::uidToName(uid_t uid) {
    // Local hard coded favourites
@@ -191,12 +228,22 @@ char *LogStatistics::uidToName(uid_t uid) {
}

static void format_line(android::String8 &output,
        android::String8 &name, android::String8 &size) {
    static const size_t total_len = 70;

        android::String8 &name, android::String8 &size, android::String8 &pruned) {
    static const size_t pruned_len = 6;
    static const size_t total_len = 70 + pruned_len;

    ssize_t drop_len = std::max(pruned.length() + 1, pruned_len);
    ssize_t size_len = std::max(size.length() + 1,
                                total_len - name.length() - drop_len - 1);

    if (pruned.length()) {
        output.appendFormat("%s%*s%*s\n", name.string(),
                                          (int)size_len, size.string(),
                                          (int)drop_len, pruned.string());
    } else {
        output.appendFormat("%s%*s\n", name.string(),
        (int)std::max(total_len - name.length() - 1, size.length() + 1),
        size.string());
                                       (int)size_len, size.string());
    }
}

void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
@@ -285,14 +332,18 @@ void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
                    output.appendFormat(
                        "\n\nChattiest UIDs in %s:\n",
                        android_log_id_to_name(id));
                    android::String8 name("UID");
                    android::String8 size("Size");
                    format_line(output, name, size);
                } else {
                    output.appendFormat(
                        "\n\nLogging for your UID in %s:\n",
                        android_log_id_to_name(id));
                }
                android::String8 name("UID");
                android::String8 size("Size");
                android::String8 pruned("Pruned");
                if (!worstUidEnabledForLogid(id)) {
                    pruned.setTo("");
                }
                format_line(output, name, size, pruned);
                headerPrinted = true;
            }

@@ -307,7 +358,13 @@ void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
            android::String8 size("");
            size.appendFormat("%zu", entry->getSizes());

            format_line(output, name, size);
            android::String8 pruned("");
            size_t dropped = entry->getDropped();
            if (dropped) {
                pruned.appendFormat("%zu", dropped);
            }

            format_line(output, name, size, pruned);
        }
    }

@@ -330,7 +387,8 @@ void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
                }
                android::String8 name("  PID/UID");
                android::String8 size("Size");
                format_line(output, name, size);
                android::String8 pruned("Pruned");
                format_line(output, name, size, pruned);
                headerPrinted = true;
            }

@@ -350,7 +408,13 @@ void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
            android::String8 size("");
            size.appendFormat("%zu", entry->getSizes());

            format_line(output, name, size);
            android::String8 pruned("");
            size_t dropped = entry->getDropped();
            if (dropped) {
                pruned.appendFormat("%zu", dropped);
            }

            format_line(output, name, size, pruned);
        }
    }

Loading