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