1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker #ifndef CAMERA2COMMON_H
17*ec779b8eSAndroid Build Coastguard Worker #define CAMERA2COMMON_H
18*ec779b8eSAndroid Build Coastguard Worker
19*ec779b8eSAndroid Build Coastguard Worker #include <CameraSessionStats.h>
20*ec779b8eSAndroid Build Coastguard Worker #include <android-base/logging.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <binder/Parcel.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <fuzzbinder/random_binder.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <fuzzbinder/random_fd.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <fuzzbinder/random_parcel.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <fuzzer/FuzzedDataProvider.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <utils/String16.h>
28*ec779b8eSAndroid Build Coastguard Worker
29*ec779b8eSAndroid Build Coastguard Worker using namespace android;
30*ec779b8eSAndroid Build Coastguard Worker
31*ec779b8eSAndroid Build Coastguard Worker const std::string kFetchCameraService = "media.camera";
32*ec779b8eSAndroid Build Coastguard Worker
33*ec779b8eSAndroid Build Coastguard Worker constexpr int8_t kMinIterations = 0;
34*ec779b8eSAndroid Build Coastguard Worker constexpr int8_t kMaxIterations = 20;
35*ec779b8eSAndroid Build Coastguard Worker constexpr int8_t kMinExtraFDs = 0;
36*ec779b8eSAndroid Build Coastguard Worker constexpr int8_t kMinExtraBinder = 0;
37*ec779b8eSAndroid Build Coastguard Worker constexpr int32_t kMaxFDs = 1000;
38*ec779b8eSAndroid Build Coastguard Worker constexpr int32_t kMinBytes = 0;
39*ec779b8eSAndroid Build Coastguard Worker constexpr int32_t kMaxBytes = 20;
40*ec779b8eSAndroid Build Coastguard Worker constexpr int32_t kMinCapacity = 1;
41*ec779b8eSAndroid Build Coastguard Worker constexpr int32_t kMaxCapacity = 1000;
42*ec779b8eSAndroid Build Coastguard Worker
43*ec779b8eSAndroid Build Coastguard Worker const int32_t kValidFacing[] = {android::hardware::CameraSessionStats::CAMERA_FACING_BACK,
44*ec779b8eSAndroid Build Coastguard Worker android::hardware::CameraSessionStats::CAMERA_FACING_FRONT};
45*ec779b8eSAndroid Build Coastguard Worker const int32_t kValidOrientation[] = {0, 90, 180, 270};
46*ec779b8eSAndroid Build Coastguard Worker
randomizeParcel(Parcel * parcel,FuzzedDataProvider & provider)47*ec779b8eSAndroid Build Coastguard Worker void randomizeParcel(Parcel* parcel, FuzzedDataProvider& provider) {
48*ec779b8eSAndroid Build Coastguard Worker sp<IServiceManager> sm = defaultServiceManager();
49*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = sm->getService(String16(kFetchCameraService.c_str()));
50*ec779b8eSAndroid Build Coastguard Worker RandomParcelOptions options{
51*ec779b8eSAndroid Build Coastguard Worker .extraBinders = {binder},
52*ec779b8eSAndroid Build Coastguard Worker .extraFds = {},
53*ec779b8eSAndroid Build Coastguard Worker };
54*ec779b8eSAndroid Build Coastguard Worker
55*ec779b8eSAndroid Build Coastguard Worker auto retFds = parcel->debugReadAllFileDescriptors();
56*ec779b8eSAndroid Build Coastguard Worker for (size_t i = 0; i < retFds.size(); ++i) {
57*ec779b8eSAndroid Build Coastguard Worker options.extraFds.push_back(base::unique_fd(dup(retFds[i])));
58*ec779b8eSAndroid Build Coastguard Worker }
59*ec779b8eSAndroid Build Coastguard Worker int8_t iterations = provider.ConsumeIntegralInRange<int8_t>(kMinIterations, kMaxIterations);
60*ec779b8eSAndroid Build Coastguard Worker while (--iterations >= 0) {
61*ec779b8eSAndroid Build Coastguard Worker auto fillFunc = provider.PickValueInArray<const std::function<void()>>({
62*ec779b8eSAndroid Build Coastguard Worker // write data
63*ec779b8eSAndroid Build Coastguard Worker [&]() {
64*ec779b8eSAndroid Build Coastguard Worker size_t toWrite = provider.ConsumeIntegralInRange<size_t>(kMinBytes, kMaxBytes);
65*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t> data = provider.ConsumeBytes<uint8_t>(toWrite);
66*ec779b8eSAndroid Build Coastguard Worker CHECK(OK == parcel->write(data.data(), data.size()));
67*ec779b8eSAndroid Build Coastguard Worker },
68*ec779b8eSAndroid Build Coastguard Worker // write FD
69*ec779b8eSAndroid Build Coastguard Worker [&]() {
70*ec779b8eSAndroid Build Coastguard Worker if (options.extraFds.size() > 0 && provider.ConsumeBool()) {
71*ec779b8eSAndroid Build Coastguard Worker const base::unique_fd& fd =
72*ec779b8eSAndroid Build Coastguard Worker options.extraFds.at(provider.ConsumeIntegralInRange<size_t>(
73*ec779b8eSAndroid Build Coastguard Worker kMinExtraFDs, options.extraFds.size() - 1));
74*ec779b8eSAndroid Build Coastguard Worker CHECK(OK == parcel->writeFileDescriptor(fd.get(), false /*takeOwnership*/));
75*ec779b8eSAndroid Build Coastguard Worker } else {
76*ec779b8eSAndroid Build Coastguard Worker // b/260119717 - Adding more FDs can eventually lead to FD limit exhaustion
77*ec779b8eSAndroid Build Coastguard Worker if (options.extraFds.size() > kMaxFDs) {
78*ec779b8eSAndroid Build Coastguard Worker return;
79*ec779b8eSAndroid Build Coastguard Worker }
80*ec779b8eSAndroid Build Coastguard Worker
81*ec779b8eSAndroid Build Coastguard Worker std::vector<base::unique_fd> fds = getRandomFds(&provider);
82*ec779b8eSAndroid Build Coastguard Worker CHECK(OK == parcel->writeFileDescriptor(fds.begin()->release(),
83*ec779b8eSAndroid Build Coastguard Worker true /*takeOwnership*/));
84*ec779b8eSAndroid Build Coastguard Worker
85*ec779b8eSAndroid Build Coastguard Worker options.extraFds.insert(options.extraFds.end(),
86*ec779b8eSAndroid Build Coastguard Worker std::make_move_iterator(fds.begin() + 1),
87*ec779b8eSAndroid Build Coastguard Worker std::make_move_iterator(fds.end()));
88*ec779b8eSAndroid Build Coastguard Worker }
89*ec779b8eSAndroid Build Coastguard Worker },
90*ec779b8eSAndroid Build Coastguard Worker // write binder
91*ec779b8eSAndroid Build Coastguard Worker [&]() {
92*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder;
93*ec779b8eSAndroid Build Coastguard Worker if (options.extraBinders.size() > 0 && provider.ConsumeBool()) {
94*ec779b8eSAndroid Build Coastguard Worker binder = options.extraBinders.at(provider.ConsumeIntegralInRange<size_t>(
95*ec779b8eSAndroid Build Coastguard Worker kMinExtraBinder, options.extraBinders.size() - 1));
96*ec779b8eSAndroid Build Coastguard Worker } else {
97*ec779b8eSAndroid Build Coastguard Worker binder = getRandomBinder(&provider);
98*ec779b8eSAndroid Build Coastguard Worker }
99*ec779b8eSAndroid Build Coastguard Worker CHECK(OK == parcel->writeStrongBinder(binder));
100*ec779b8eSAndroid Build Coastguard Worker },
101*ec779b8eSAndroid Build Coastguard Worker });
102*ec779b8eSAndroid Build Coastguard Worker fillFunc();
103*ec779b8eSAndroid Build Coastguard Worker }
104*ec779b8eSAndroid Build Coastguard Worker }
105*ec779b8eSAndroid Build Coastguard Worker
106*ec779b8eSAndroid Build Coastguard Worker template <class type>
invokeReadWriteNullParcel(type * obj)107*ec779b8eSAndroid Build Coastguard Worker void invokeReadWriteNullParcel(type* obj) {
108*ec779b8eSAndroid Build Coastguard Worker Parcel* parcelNull = nullptr;
109*ec779b8eSAndroid Build Coastguard Worker obj->writeToParcel(parcelNull);
110*ec779b8eSAndroid Build Coastguard Worker obj->readFromParcel(parcelNull);
111*ec779b8eSAndroid Build Coastguard Worker }
112*ec779b8eSAndroid Build Coastguard Worker
113*ec779b8eSAndroid Build Coastguard Worker template <class type>
invokeReadWriteNullParcelsp(sp<type> obj)114*ec779b8eSAndroid Build Coastguard Worker void invokeReadWriteNullParcelsp(sp<type> obj) {
115*ec779b8eSAndroid Build Coastguard Worker Parcel* parcelNull = nullptr;
116*ec779b8eSAndroid Build Coastguard Worker obj->writeToParcel(parcelNull);
117*ec779b8eSAndroid Build Coastguard Worker obj->readFromParcel(parcelNull);
118*ec779b8eSAndroid Build Coastguard Worker }
119*ec779b8eSAndroid Build Coastguard Worker
120*ec779b8eSAndroid Build Coastguard Worker template <class type>
invokeReadWriteParcel(type * obj)121*ec779b8eSAndroid Build Coastguard Worker void invokeReadWriteParcel(type* obj) {
122*ec779b8eSAndroid Build Coastguard Worker Parcel* parcel = new Parcel();
123*ec779b8eSAndroid Build Coastguard Worker obj->writeToParcel(parcel);
124*ec779b8eSAndroid Build Coastguard Worker parcel->setDataPosition(0);
125*ec779b8eSAndroid Build Coastguard Worker obj->readFromParcel(parcel);
126*ec779b8eSAndroid Build Coastguard Worker delete parcel;
127*ec779b8eSAndroid Build Coastguard Worker }
128*ec779b8eSAndroid Build Coastguard Worker
129*ec779b8eSAndroid Build Coastguard Worker template <class type>
invokeReadWriteParcelsp(sp<type> obj)130*ec779b8eSAndroid Build Coastguard Worker void invokeReadWriteParcelsp(sp<type> obj) {
131*ec779b8eSAndroid Build Coastguard Worker Parcel* parcel = new Parcel();
132*ec779b8eSAndroid Build Coastguard Worker obj->writeToParcel(parcel);
133*ec779b8eSAndroid Build Coastguard Worker parcel->setDataPosition(0);
134*ec779b8eSAndroid Build Coastguard Worker obj->readFromParcel(parcel);
135*ec779b8eSAndroid Build Coastguard Worker delete parcel;
136*ec779b8eSAndroid Build Coastguard Worker }
137*ec779b8eSAndroid Build Coastguard Worker
138*ec779b8eSAndroid Build Coastguard Worker template <class type>
invokeNewReadWriteParcel(type * obj,FuzzedDataProvider & provider)139*ec779b8eSAndroid Build Coastguard Worker void invokeNewReadWriteParcel(type* obj, FuzzedDataProvider& provider) {
140*ec779b8eSAndroid Build Coastguard Worker Parcel* parcel = new Parcel();
141*ec779b8eSAndroid Build Coastguard Worker obj->writeToParcel(parcel);
142*ec779b8eSAndroid Build Coastguard Worker randomizeParcel(parcel, provider);
143*ec779b8eSAndroid Build Coastguard Worker parcel->setDataPosition(0);
144*ec779b8eSAndroid Build Coastguard Worker obj->readFromParcel(parcel);
145*ec779b8eSAndroid Build Coastguard Worker delete parcel;
146*ec779b8eSAndroid Build Coastguard Worker }
147*ec779b8eSAndroid Build Coastguard Worker
148*ec779b8eSAndroid Build Coastguard Worker template <class type>
invokeNewReadWriteParcelsp(sp<type> obj,FuzzedDataProvider & provider)149*ec779b8eSAndroid Build Coastguard Worker void invokeNewReadWriteParcelsp(sp<type> obj, FuzzedDataProvider& provider) {
150*ec779b8eSAndroid Build Coastguard Worker Parcel* parcel = new Parcel();
151*ec779b8eSAndroid Build Coastguard Worker obj->writeToParcel(parcel);
152*ec779b8eSAndroid Build Coastguard Worker randomizeParcel(parcel, provider);
153*ec779b8eSAndroid Build Coastguard Worker parcel->setDataPosition(0);
154*ec779b8eSAndroid Build Coastguard Worker obj->readFromParcel(parcel);
155*ec779b8eSAndroid Build Coastguard Worker delete parcel;
156*ec779b8eSAndroid Build Coastguard Worker }
157*ec779b8eSAndroid Build Coastguard Worker
158*ec779b8eSAndroid Build Coastguard Worker #endif // CAMERA2COMMON_H
159