• 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 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