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

Commit da88195b authored by Marissa Wall's avatar Marissa Wall
Browse files

gralloc: fuzz libgralloctypes

Libgralloctypes decodes byte streams from remote processes. This
fuzzer fuzzes all of libgralloctypes decode functions to make
sure there aren't any vulnerabilites.

This patch borrows heavily from binder_parcel_fuzzer.

Bug: 141632767
Test: SANITIZE_HOST=address make libgralloctypes_fuzzer
      ${ANDROID_HOST_OUT}/fuzz/<arch>/libgralloctypes_fuzzer/libgralloctypes_fuzzer

Change-Id: I24e01570ac79f47cad1eff2eb68cb70201a4644d
parent 4858652a
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
cc_fuzz {
    name: "libgralloctypes_fuzzer",
    defaults: ["libbinder_ndk_host_user"],
    host_supported: true,

    fuzz_config: {
        cc: ["marissaw@google.com"],
    },

    srcs: [
        "gralloctypes.cpp",
        "main.cpp",
        "util.cpp",
    ],
    static_libs: [
        "libbase",
        "libcgrouprc",
        "libcgrouprc_format",
        "libcutils",
        "libgralloctypes",
        "libhidlbase",
        "liblog",
        "libprocessgroup",
        "libjsoncpp",
        "libutils",
    ],

    // This flag enables verbose output in the fuzz target, and is very useful
    // for debugging a failure. If you are trying to diagnose how a crash was
    // produced, you may find uncommenting the below line very useful.
    // cflags: ["-DENABLE_LOG_FUZZ"],
}
+64 −0
Original line number Diff line number Diff line
/*
 * 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.
 */
#define FUZZ_LOG_TAG "gralloctypes"

#include <cstdint>

#include <aidl/android/hardware/graphics/common/BlendMode.h>
#include <aidl/android/hardware/graphics/common/Dataspace.h>
#include <aidl/android/hardware/graphics/common/ExtendableType.h>
#include <aidl/android/hardware/graphics/common/PlaneLayout.h>
#include <android/hardware/graphics/common/1.2/types.h>
#include <gralloctypes/Gralloc4.h>
#include <hidl/HidlSupport.h>
#include <utils/Errors.h>

#include "gralloctypes.h"
#include "util.h"

using ::android::status_t;

#define GRALLOCTYPES_DECODE(T, FUNC) \
    [] (const ::android::hardware::hidl_vec<uint8_t>& vec, uint8_t /*data*/) {\
        FUZZ_LOG() << "about to read " #T " using " #FUNC;\
        T t;\
        status_t err = FUNC(vec, &t);\
        (void) err;\
        FUZZ_LOG() << #T " done " /* << "err: " << err*/;\
    }


// clang-format off
std::vector<GrallocTypesDecode> GRALLOCTYPES_DECODE_FUNCTIONS {
    GRALLOCTYPES_DECODE(uint64_t, ::android::gralloc4::decodeBufferId),
    GRALLOCTYPES_DECODE(std::string, ::android::gralloc4::decodeName),
    GRALLOCTYPES_DECODE(uint64_t, ::android::gralloc4::decodeWidth),
    GRALLOCTYPES_DECODE(uint64_t, ::android::gralloc4::decodeHeight),
    GRALLOCTYPES_DECODE(uint64_t, ::android::gralloc4::decodeLayerCount),
    GRALLOCTYPES_DECODE(::android::hardware::graphics::common::V1_2::PixelFormat, ::android::gralloc4::decodePixelFormatRequested),
    GRALLOCTYPES_DECODE(uint32_t, ::android::gralloc4::decodePixelFormatFourCC),
    GRALLOCTYPES_DECODE(uint64_t, ::android::gralloc4::decodePixelFormatModifier),
    GRALLOCTYPES_DECODE(uint64_t, ::android::gralloc4::decodeUsage),
    GRALLOCTYPES_DECODE(uint64_t, ::android::gralloc4::decodeAllocationSize),
    GRALLOCTYPES_DECODE(uint64_t, ::android::gralloc4::decodeProtectedContent),
    GRALLOCTYPES_DECODE(aidl::android::hardware::graphics::common::ExtendableType, ::android::gralloc4::decodeCompression),
    GRALLOCTYPES_DECODE(aidl::android::hardware::graphics::common::ExtendableType, ::android::gralloc4::decodeInterlaced),
    GRALLOCTYPES_DECODE(aidl::android::hardware::graphics::common::ExtendableType, ::android::gralloc4::decodeChromaSiting),
    GRALLOCTYPES_DECODE(std::vector<aidl::android::hardware::graphics::common::PlaneLayout>, ::android::gralloc4::decodePlaneLayouts),
    GRALLOCTYPES_DECODE(aidl::android::hardware::graphics::common::Dataspace, ::android::gralloc4::decodeDataspace),
    GRALLOCTYPES_DECODE(aidl::android::hardware::graphics::common::BlendMode, ::android::gralloc4::decodeBlendMode),
};
// clang-format on
+25 −0
Original line number Diff line number Diff line
/*
 * 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.
 */
#pragma once

#include <gralloctypes/Gralloc4.h>
#include <hidl/HidlSupport.h>

#include <vector>

using GrallocTypesDecode = std::function<void(const ::android::hardware::hidl_vec<uint8_t>& vec, uint8_t data)>;

extern std::vector<GrallocTypesDecode> GRALLOCTYPES_DECODE_FUNCTIONS;
+75 −0
Original line number Diff line number Diff line
/*
 * 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.
 */
#define FUZZ_LOG_TAG "main"

#include "gralloctypes.h"
#include "util.h"

#include <android-base/logging.h>
#include <log/log.h>

#include <cstdlib>
#include <ctime>

void doFuzz(
        const std::vector<GrallocTypesDecode>& decodes,
        const std::vector<uint8_t>& input,
        const std::vector<uint8_t>& instructions) {

    ::android::hardware::hidl_vec<uint8_t> vec;
    vec.setToExternal(const_cast<uint8_t*>(input.data()), input.size(), false /*shouldOwn*/);

    // since we are only using a byte to index
    CHECK(decodes.size() <= 255) << decodes.size();

    for (size_t i = 0; i < instructions.size() - 1; i += 2) {
        uint8_t a = instructions[i];
        uint8_t decodeIdx = a % decodes.size();

        uint8_t b = instructions[i + 1];

        FUZZ_LOG() << "Instruction: " << (i / 2) + 1 << "/" << instructions.size() / 2
                   << " cmd: " << static_cast<size_t>(a) << " (" << static_cast<size_t>(decodeIdx)
                   << ") arg: " << static_cast<size_t>(b) << " size: " << vec.size();

        decodes[decodeIdx](vec, b);
    }
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    if (size <= 1) return 0;  // no use

    // data to fill out parcel
    size_t inputLen = size / 2;
    std::vector<uint8_t> input(data, data + inputLen);
    data += inputLen;
    size -= inputLen;

    // data to use to determine what to do
    size_t instructionLen = size;
    std::vector<uint8_t> instructions(data, data + instructionLen);
    data += instructionLen;
    size -= instructionLen;

    CHECK(size == 0) << "size: " << size;

    FUZZ_LOG() << "inputLen: " << inputLen << " instructionLen: " << instructionLen;
    FUZZ_LOG() << "input: " << hexString(input);
    FUZZ_LOG() << "instructions: " << hexString(instructions);

    doFuzz(GRALLOCTYPES_DECODE_FUNCTIONS, input, instructions);
    return 0;
}
+41 −0
Original line number Diff line number Diff line
/*
 * 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.
 */
#define FUZZ_LOG_TAG "util"
#include "util.h"

#include <android-base/logging.h>

#include <iomanip>
#include <sstream>

std::string hexString(const void* bytes, size_t len) {
    if (bytes == nullptr) return "<null>";

    const uint8_t* bytes8 = static_cast<const uint8_t*>(bytes);
    char chars[] = "0123456789abcdef";
    std::string result;
    result.resize(len * 2);

    for (size_t i = 0; i < len; i++) {
        result[2 * i] = chars[bytes8[i] >> 4];
        result[2 * i + 1] = chars[bytes8[i] & 0xf];
    }

    return result;
}
std::string hexString(const std::vector<uint8_t>& bytes) {
    return hexString(bytes.data(), bytes.size());
}
Loading