From ace90bd945372071315248ba04e8e86ce665c494 Mon Sep 17 00:00:00 2001 From: Max Spector Date: Mon, 21 Oct 2019 11:40:43 -0700 Subject: [PATCH] Liblogd log fuzzer Improvments to fuzzer for liblogd LogBuffer::log Bug: 143107334 Test: Ran the fuzzer Change-Id: Ibf9f21cd51ff7c0ef390a5e217be085a9a4976e0 --- logd/fuzz/Android.bp | 28 ++++++++------- logd/fuzz/log_buffer_log_fuzzer.cpp | 53 +++++++++++++++++++---------- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/logd/fuzz/Android.bp b/logd/fuzz/Android.bp index 3215b2458..299242db6 100644 --- a/logd/fuzz/Android.bp +++ b/logd/fuzz/Android.bp @@ -1,16 +1,18 @@ -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ cc_fuzz { name: "log_buffer_log_fuzzer", srcs: [ diff --git a/logd/fuzz/log_buffer_log_fuzzer.cpp b/logd/fuzz/log_buffer_log_fuzzer.cpp index be4c7c35f..4d1589b50 100644 --- a/logd/fuzz/log_buffer_log_fuzzer.cpp +++ b/logd/fuzz/log_buffer_log_fuzzer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,64 +13,79 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include + #include "../LogBuffer.h" #include "../LogTimes.h" +// We don't want to waste a lot of entropy on messages +#define MAX_MSG_LENGTH 5 + +// Tag IDs usually start at 1000, we only want to try 1000 through 1009 +#define MIN_TAG_ID 1000 +#define TAG_MOD 10 + namespace android { struct LogInput { public: - log_id_t log_id; // char + log_id_t log_id; log_time realtime; uid_t uid; pid_t pid; pid_t tid; + unsigned int log_mask; }; -int write_log_messages(const uint8_t* data, size_t* data_left, LogBuffer* log_buffer) { +int write_log_messages(const uint8_t** pdata, size_t* data_left, LogBuffer* log_buffer) { + const uint8_t* data = *pdata; const LogInput* logInput = reinterpret_cast(data); data += sizeof(LogInput); *data_left -= sizeof(LogInput); - uint8_t tag_length = data[0] % 32; - uint8_t msg_length = data[1] % 32; - if (tag_length < 2 || msg_length < 2) { - // Not enough data for tag and message + uint32_t tag = MIN_TAG_ID + data[0] % TAG_MOD; + uint8_t msg_length = data[1] % MAX_MSG_LENGTH; + if (msg_length < 2) { + // Not enough data for message return 0; } data += 2 * sizeof(uint8_t); *data_left -= 2 * sizeof(uint8_t); - if (*data_left < tag_length + msg_length) { + if (*data_left < msg_length) { // Not enough data for tag and message + *pdata = data; return 0; } // We need nullterm'd strings - char* msg = new char[tag_length + msg_length + 2]; - char* msg_only = msg + tag_length + 1; - memcpy(msg, data, tag_length); - msg[tag_length] = '\0'; + char msg[sizeof(uint32_t) + MAX_MSG_LENGTH + sizeof(char)]; + char* msg_only = msg + sizeof(uint32_t); + memcpy(msg, &tag, sizeof(uint32_t)); memcpy(msg_only, data, msg_length); msg_only[msg_length] = '\0'; - data += tag_length + msg_length; - *data_left -= tag_length + msg_length; + data += msg_length; + *data_left -= msg_length; // Other elements not in enum. log_id_t log_id = static_cast(unsigned(logInput->log_id) % (LOG_ID_MAX + 1)); log_buffer->log(log_id, logInput->realtime, logInput->uid, logInput->pid, logInput->tid, msg, - tag_length + msg_length + 2); - delete[] msg; + sizeof(uint32_t) + msg_length + 1); + log_buffer->formatStatistics(logInput->uid, logInput->pid, logInput->log_mask); + *pdata = data; return 1; } -// Because system/core/logd/main.cpp redefines this. +// Because system/core/logd/main.cpp redefines these. void prdebug(char const* fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } +char* uidToName(uid_t) { + return strdup("fake"); +} extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // We want a random tag length and a random remaining message length @@ -81,13 +96,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { LastLogTimes times; LogBuffer log_buffer(×); size_t data_left = size; + const uint8_t** pdata = &data; log_buffer.enableStatistics(); + log_buffer.initPrune(nullptr); // We want to get pruning code to get called. log_id_for_each(i) { log_buffer.setSize(i, 10000); } while (data_left >= sizeof(LogInput) + 2 * sizeof(uint8_t)) { - if (!write_log_messages(data, &data_left, &log_buffer)) { + if (!write_log_messages(pdata, &data_left, &log_buffer)) { return 0; } }