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