blob: e14d9ce5e67125ce8d35dc79dfcf419f19072b44 [file] [log] [blame]
/*
* Copyright (C) 2022 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.
*/
#include <VendorTagDescriptor.h>
#include <binder/Parcel.h>
#include <camera_metadata_tests_fake_vendor.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <system/camera_vendor_tags.h>
#include <camera_metadata_hidden.h>
#include "camera2common.h"
using namespace std;
using namespace android;
constexpr int32_t kRangeMin = 0;
constexpr int32_t kRangeMax = 1000;
constexpr int32_t kVendorTagDescriptorId = -1;
extern "C" {
static int zero_get_tag_count(const vendor_tag_ops_t*) {
return 0;
}
static int default_get_tag_count(const vendor_tag_ops_t*) {
return VENDOR_TAG_COUNT_ERR;
}
static void default_get_all_tags(const vendor_tag_ops_t*, uint32_t*) {}
static const char* default_get_section_name(const vendor_tag_ops_t*, uint32_t) {
return VENDOR_SECTION_NAME_ERR;
}
static const char* default_get_tag_name(const vendor_tag_ops_t*, uint32_t) {
return VENDOR_TAG_NAME_ERR;
}
static int default_get_tag_type(const vendor_tag_ops_t*, uint32_t) {
return VENDOR_TAG_TYPE_ERR;
}
} /*extern "C"*/
static void FillWithDefaults(vendor_tag_ops_t* vOps) {
vOps->get_tag_count = default_get_tag_count;
vOps->get_all_tags = default_get_all_tags;
vOps->get_section_name = default_get_section_name;
vOps->get_tag_name = default_get_tag_name;
vOps->get_tag_type = default_get_tag_type;
}
class VendorTagDescriptorFuzzer {
public:
void process(const uint8_t* data, size_t size);
~VendorTagDescriptorFuzzer() {
mVendorTagDescriptor.clear();
mVendorTagDescriptorCache.clear();
}
private:
void initVendorTagDescriptor();
void invokeVendorTagDescriptor();
void invokeVendorTagDescriptorCache();
void invokeVendorTagErrorConditions();
sp<VendorTagDescriptor> mVendorTagDescriptor = nullptr;
sp<VendorTagDescriptorCache> mVendorTagDescriptorCache = nullptr;
FuzzedDataProvider* mFDP = nullptr;
};
void VendorTagDescriptorFuzzer::initVendorTagDescriptor() {
if (mFDP->ConsumeBool()) {
mVendorTagDescriptor = new VendorTagDescriptor();
} else {
const vendor_tag_ops_t* vOps = &fakevendor_ops;
VendorTagDescriptor::createDescriptorFromOps(vOps, mVendorTagDescriptor);
}
}
void VendorTagDescriptorFuzzer::invokeVendorTagDescriptor() {
initVendorTagDescriptor();
sp<VendorTagDescriptor> vdesc = new VendorTagDescriptor();
vdesc->copyFrom(*mVendorTagDescriptor);
VendorTagDescriptor::setAsGlobalVendorTagDescriptor(mVendorTagDescriptor);
VendorTagDescriptor::getGlobalVendorTagDescriptor();
int32_t tagCount = mVendorTagDescriptor->getTagCount();
if (tagCount > 0) {
uint32_t tagArray[tagCount];
mVendorTagDescriptor->getTagArray(tagArray);
uint32_t tag;
for (int32_t i = 0; i < tagCount; ++i) {
tag = tagArray[i];
get_local_camera_metadata_section_name_vendor_id(tag, kVendorTagDescriptorId);
get_local_camera_metadata_tag_name_vendor_id(tag, kVendorTagDescriptorId);
get_local_camera_metadata_tag_type_vendor_id(tag, kVendorTagDescriptorId);
mVendorTagDescriptor->getSectionIndex(tag);
}
mVendorTagDescriptor->getAllSectionNames();
}
String8 name((mFDP->ConsumeRandomLengthString()).c_str());
String8 section((mFDP->ConsumeRandomLengthString()).c_str());
uint32_t lookupTag;
mVendorTagDescriptor->lookupTag(name, section, &lookupTag);
int32_t fd = open("/dev/null", O_CLOEXEC | O_RDWR | O_CREAT);
int32_t verbosity = mFDP->ConsumeIntegralInRange<int32_t>(kRangeMin, kRangeMax);
int32_t indentation = mFDP->ConsumeIntegralInRange<int32_t>(kRangeMin, kRangeMax);
mVendorTagDescriptor->dump(fd, verbosity, indentation);
invokeReadWriteParcelsp<VendorTagDescriptor>(mVendorTagDescriptor);
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
vdesc.clear();
close(fd);
}
void VendorTagDescriptorFuzzer::invokeVendorTagDescriptorCache() {
mVendorTagDescriptorCache = new VendorTagDescriptorCache();
uint64_t id = mFDP->ConsumeIntegral<uint64_t>();
initVendorTagDescriptor();
mVendorTagDescriptorCache->addVendorDescriptor(id, mVendorTagDescriptor);
VendorTagDescriptorCache::setAsGlobalVendorTagCache(mVendorTagDescriptorCache);
VendorTagDescriptorCache::getGlobalVendorTagCache();
sp<VendorTagDescriptor> tagDesc;
mVendorTagDescriptorCache->getVendorTagDescriptor(id, &tagDesc);
int32_t tagCount = mVendorTagDescriptorCache->getTagCount(id);
if (tagCount > 0) {
uint32_t tagArray[tagCount];
mVendorTagDescriptorCache->getTagArray(tagArray, id);
uint32_t tag;
for (int32_t i = 0; i < tagCount; ++i) {
tag = tagArray[i];
get_local_camera_metadata_section_name_vendor_id(tag, id);
get_local_camera_metadata_tag_name_vendor_id(tag, id);
get_local_camera_metadata_tag_type_vendor_id(tag, id);
}
}
int32_t fd = open("/dev/null", O_CLOEXEC | O_RDWR | O_CREAT);
int32_t verbosity = mFDP->ConsumeIntegralInRange<int>(kRangeMin, kRangeMax);
int32_t indentation = mFDP->ConsumeIntegralInRange<int>(kRangeMin, kRangeMax);
mVendorTagDescriptorCache->dump(fd, verbosity, indentation);
invokeReadWriteParcelsp<VendorTagDescriptorCache>(mVendorTagDescriptorCache);
VendorTagDescriptorCache::isVendorCachePresent(id);
mVendorTagDescriptorCache->getVendorIdsAndTagDescriptors();
mVendorTagDescriptorCache->clearGlobalVendorTagCache();
tagDesc.clear();
close(fd);
}
void VendorTagDescriptorFuzzer::invokeVendorTagErrorConditions() {
sp<VendorTagDescriptor> vDesc;
vendor_tag_ops_t vOps;
FillWithDefaults(&vOps);
vOps.get_tag_count = zero_get_tag_count;
if (mFDP->ConsumeBool()) {
VendorTagDescriptor::createDescriptorFromOps(/*vOps*/ NULL, vDesc);
} else {
VendorTagDescriptor::createDescriptorFromOps(&vOps, vDesc);
int32_t tagCount = vDesc->getTagCount();
uint32_t badTag = mFDP->ConsumeIntegral<uint32_t>();
uint32_t badTagArray[tagCount + 1];
vDesc->getTagArray(badTagArray);
vDesc->getSectionName(badTag);
vDesc->getTagName(badTag);
vDesc->getTagType(badTag);
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
VendorTagDescriptor::getGlobalVendorTagDescriptor();
VendorTagDescriptor::setAsGlobalVendorTagDescriptor(vDesc);
invokeReadWriteNullParcelsp<VendorTagDescriptor>(vDesc);
vDesc.clear();
}
}
void VendorTagDescriptorFuzzer::process(const uint8_t* data, size_t size) {
mFDP = new FuzzedDataProvider(data, size);
invokeVendorTagDescriptor();
invokeVendorTagDescriptorCache();
invokeVendorTagErrorConditions();
delete mFDP;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
VendorTagDescriptorFuzzer vendorTagDescriptorFuzzer;
vendorTagDescriptorFuzzer.process(data, size);
return 0;
}