• 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 #include <fuzzbinder/random_binder.h>
17 
18 #include <fuzzbinder/random_parcel.h>
19 
20 #include <android-base/logging.h>
21 #include <binder/IInterface.h>
22 #include <binder/IServiceManager.h>
23 
24 namespace android {
25 
26 class RandomBinder : public BBinder {
27 public:
RandomBinder(const String16 & descriptor,std::vector<uint8_t> && bytes)28     RandomBinder(const String16& descriptor, std::vector<uint8_t>&& bytes)
29           : mDescriptor(descriptor),
30             mBytes(std::move(bytes)),
31             mProvider(mBytes.data(), mBytes.size()) {}
getInterfaceDescriptor() const32     const String16& getInterfaceDescriptor() const override { return mDescriptor; }
33 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)34     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override {
35         (void)code;
36         (void)data;
37         (void)reply;
38         (void)flags; // note - for maximum coverage even ignore if oneway
39 
40         if (mProvider.ConsumeBool()) {
41             return mProvider.ConsumeIntegral<status_t>();
42         }
43 
44         if (reply == nullptr) return OK;
45 
46         // TODO: things we could do to increase state space
47         // - also pull FDs and binders from 'data'
48         //     (optionally combine these into random parcel 'options')
49         // - also pull FDs and binders from random parcel 'options'
50         RandomParcelOptions options;
51 
52         // random output
53         std::vector<uint8_t> subData = mProvider.ConsumeBytes<uint8_t>(
54                 mProvider.ConsumeIntegralInRange<size_t>(0, mProvider.remaining_bytes()));
55         fillRandomParcel(reply, FuzzedDataProvider(subData.data(), subData.size()), &options);
56 
57         return OK;
58     }
59 
60 private:
61     String16 mDescriptor;
62 
63     // note may not all be used
64     std::vector<uint8_t> mBytes;
65     FuzzedDataProvider mProvider;
66 };
67 
getRandomBinder(FuzzedDataProvider * provider)68 sp<IBinder> getRandomBinder(FuzzedDataProvider* provider) {
69     auto makeFunc = provider->PickValueInArray<const std::function<sp<IBinder>()>>({
70             [&]() {
71                 // descriptor is the length of a class name, e.g.
72                 // "some.package.Foo"
73                 std::string str = provider->ConsumeRandomLengthString(100 /*max length*/);
74 
75                 // arbitrarily consume remaining data to create a binder that can return
76                 // random results - coverage guided fuzzer should ensure all of the remaining
77                 // data isn't always used
78                 std::vector<uint8_t> bytes = provider->ConsumeBytes<uint8_t>(
79                         provider->ConsumeIntegralInRange<size_t>(0, provider->remaining_bytes()));
80 
81                 return new RandomBinder(String16(str.c_str()), std::move(bytes));
82             },
83             []() {
84                 // this is the easiest remote binder to get ahold of, and it
85                 // should be able to handle anything thrown at it, and
86                 // essentially every process can talk to it, so it's a good
87                 // candidate for checking usage of an actual BpBinder
88                 return IInterface::asBinder(defaultServiceManager());
89             },
90             [&]() -> sp<IBinder> { return nullptr; },
91     });
92     return makeFunc();
93 }
94 
95 } // namespace android
96