Modified camera2common.h
Updated invokeReadWriteParcel() APIs to randomize Parcel objects.
Test: m camera_fuzzer
Bug: 309571245
Change-Id: I15e283e14bd6687414c32def7757646ea679d166
diff --git a/camera/tests/fuzzer/Android.bp b/camera/tests/fuzzer/Android.bp
index 9aecba4..6e6cf1b 100644
--- a/camera/tests/fuzzer/Android.bp
+++ b/camera/tests/fuzzer/Android.bp
@@ -26,6 +26,7 @@
name: "camera_defaults",
static_libs: [
"libcamera_client",
+ "libbinder_random_parcel",
],
shared_libs: [
"camera_platform_flags_c_lib",
@@ -38,6 +39,9 @@
"libcamera_metadata",
"libnativewindow",
],
+ header_libs: [
+ "libbinder_headers",
+ ],
fuzz_config: {
cc: [
"android-media-fuzzing-reports@google.com",
diff --git a/camera/tests/fuzzer/camera2common.h b/camera/tests/fuzzer/camera2common.h
index 14a1b1b..c82e74d 100644
--- a/camera/tests/fuzzer/camera2common.h
+++ b/camera/tests/fuzzer/camera2common.h
@@ -16,10 +16,93 @@
#ifndef CAMERA2COMMON_H
#define CAMERA2COMMON_H
+#include <CameraSessionStats.h>
+#include <android-base/logging.h>
+#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
+#include <fuzzbinder/random_binder.h>
+#include <fuzzbinder/random_fd.h>
+#include <fuzzbinder/random_parcel.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <utils/String16.h>
using namespace android;
+const std::string kFetchCameraService = "media.camera";
+
+constexpr int8_t kMinIterations = 0;
+constexpr int8_t kMaxIterations = 20;
+constexpr int8_t kMinExtraFDs = 0;
+constexpr int8_t kMinExtraBinder = 0;
+constexpr int32_t kMaxFDs = 1000;
+constexpr int32_t kMinBytes = 0;
+constexpr int32_t kMaxBytes = 20;
+constexpr int32_t kMinCapacity = 1;
+constexpr int32_t kMaxCapacity = 1000;
+
+const int32_t kValidFacing[] = {android::hardware::CameraSessionStats::CAMERA_FACING_BACK,
+ android::hardware::CameraSessionStats::CAMERA_FACING_FRONT};
+const int32_t kValidOrientation[] = {0, 90, 180, 270};
+
+void randomizeParcel(Parcel* parcel, FuzzedDataProvider& provider) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16(kFetchCameraService.c_str()));
+ RandomParcelOptions options{
+ .extraBinders = {binder},
+ .extraFds = {},
+ };
+
+ auto retFds = parcel->debugReadAllFileDescriptors();
+ for (size_t i = 0; i < retFds.size(); ++i) {
+ options.extraFds.push_back(base::unique_fd(dup(retFds[i])));
+ }
+ int8_t iterations = provider.ConsumeIntegralInRange<int8_t>(kMinIterations, kMaxIterations);
+ while (--iterations >= 0) {
+ auto fillFunc = provider.PickValueInArray<const std::function<void()>>({
+ // write data
+ [&]() {
+ size_t toWrite = provider.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes);
+ std::vector<uint8_t> data = provider.ConsumeBytes<uint8_t>(toWrite);
+ CHECK(OK == parcel->write(data.data(), data.size()));
+ },
+ // write FD
+ [&]() {
+ if (options.extraFds.size() > 0 && provider.ConsumeBool()) {
+ const base::unique_fd& fd =
+ options.extraFds.at(provider.ConsumeIntegralInRange<size_t>(
+ kMinExtraFDs, options.extraFds.size() - 1));
+ CHECK(OK == parcel->writeFileDescriptor(fd.get(), false /*takeOwnership*/));
+ } else {
+ // b/260119717 - Adding more FDs can eventually lead to FD limit exhaustion
+ if (options.extraFds.size() > kMaxFDs) {
+ return;
+ }
+
+ std::vector<base::unique_fd> fds = getRandomFds(&provider);
+ CHECK(OK == parcel->writeFileDescriptor(fds.begin()->release(),
+ true /*takeOwnership*/));
+
+ options.extraFds.insert(options.extraFds.end(),
+ std::make_move_iterator(fds.begin() + 1),
+ std::make_move_iterator(fds.end()));
+ }
+ },
+ // write binder
+ [&]() {
+ sp<IBinder> binder;
+ if (options.extraBinders.size() > 0 && provider.ConsumeBool()) {
+ binder = options.extraBinders.at(provider.ConsumeIntegralInRange<size_t>(
+ kMinExtraBinder, options.extraBinders.size() - 1));
+ } else {
+ binder = getRandomBinder(&provider);
+ }
+ CHECK(OK == parcel->writeStrongBinder(binder));
+ },
+ });
+ fillFunc();
+ }
+}
+
template <class type>
void invokeReadWriteNullParcel(type* obj) {
Parcel* parcelNull = nullptr;
@@ -52,4 +135,24 @@
delete parcel;
}
+template <class type>
+void invokeNewReadWriteParcel(type* obj, FuzzedDataProvider& provider) {
+ Parcel* parcel = new Parcel();
+ obj->writeToParcel(parcel);
+ randomizeParcel(parcel, provider);
+ parcel->setDataPosition(0);
+ obj->readFromParcel(parcel);
+ delete parcel;
+}
+
+template <class type>
+void invokeNewReadWriteParcelsp(sp<type> obj, FuzzedDataProvider& provider) {
+ Parcel* parcel = new Parcel();
+ obj->writeToParcel(parcel);
+ randomizeParcel(parcel, provider);
+ parcel->setDataPosition(0);
+ obj->readFromParcel(parcel);
+ delete parcel;
+}
+
#endif // CAMERA2COMMON_H