• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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