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