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