• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 
17 #include <fuzzbinder/random_parcel.h>
18 
19 #include <android-base/logging.h>
20 #include <binder/IServiceManager.h>
21 #include <binder/RpcSession.h>
22 #include <binder/RpcTransportRaw.h>
23 #include <fuzzbinder/random_fd.h>
24 #include <utils/String16.h>
25 
26 namespace android {
27 
28 class NamedBinder : public BBinder {
29 public:
NamedBinder(const String16 & descriptor)30     NamedBinder(const String16& descriptor) : mDescriptor(descriptor) {}
getInterfaceDescriptor() const31     const String16& getInterfaceDescriptor() const override { return mDescriptor; }
32 
33 private:
34     String16 mDescriptor;
35 };
36 
fillRandomParcelData(Parcel * p,FuzzedDataProvider && provider)37 static void fillRandomParcelData(Parcel* p, FuzzedDataProvider&& provider) {
38     std::vector<uint8_t> data = provider.ConsumeBytes<uint8_t>(provider.remaining_bytes());
39     CHECK(OK == p->write(data.data(), data.size()));
40 }
41 
fillRandomParcel(Parcel * p,FuzzedDataProvider && provider,const RandomParcelOptions & options)42 void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider,
43                       const RandomParcelOptions& options) {
44     if (provider.ConsumeBool()) {
45         auto session = RpcSession::make(RpcTransportCtxFactoryRaw::make());
46         CHECK_EQ(OK, session->addNullDebuggingClient());
47         p->markForRpc(session);
48 
49         if (options.writeHeader) {
50             options.writeHeader(p, provider);
51         }
52 
53         fillRandomParcelData(p, std::move(provider));
54         return;
55     }
56 
57     if (options.writeHeader) {
58         options.writeHeader(p, provider);
59     }
60 
61     while (provider.remaining_bytes() > 0) {
62         auto fillFunc = provider.PickValueInArray<const std::function<void()>>({
63                 // write data
64                 [&]() {
65                     size_t toWrite =
66                             provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes());
67                     std::vector<uint8_t> data = provider.ConsumeBytes<uint8_t>(toWrite);
68                     CHECK(OK == p->write(data.data(), data.size()));
69                 },
70                 // write FD
71                 [&]() {
72                     if (options.extraFds.size() > 0 && provider.ConsumeBool()) {
73                         const base::unique_fd& fd = options.extraFds.at(
74                                 provider.ConsumeIntegralInRange<size_t>(0,
75                                                                         options.extraFds.size() -
76                                                                                 1));
77                         CHECK(OK == p->writeFileDescriptor(fd.get(), false /*takeOwnership*/));
78                     } else {
79                         base::unique_fd fd = getRandomFd(&provider);
80                         CHECK(OK == p->writeFileDescriptor(fd.release(), true /*takeOwnership*/));
81                     }
82                 },
83                 // write binder
84                 [&]() {
85                     auto makeFunc = provider.PickValueInArray<const std::function<sp<IBinder>()>>({
86                             [&]() {
87                                 // descriptor is the length of a class name, e.g.
88                                 // "some.package.Foo"
89                                 std::string str =
90                                         provider.ConsumeRandomLengthString(100 /*max length*/);
91                                 return new NamedBinder(String16(str.c_str()));
92                             },
93                             []() {
94                                 // this is the easiest remote binder to get ahold of, and it
95                                 // should be able to handle anything thrown at it, and
96                                 // essentially every process can talk to it, so it's a good
97                                 // candidate for checking usage of an actual BpBinder
98                                 return IInterface::asBinder(defaultServiceManager());
99                             },
100                             [&]() -> sp<IBinder> {
101                                 if (options.extraBinders.size() > 0 && provider.ConsumeBool()) {
102                                     return options.extraBinders.at(
103                                             provider.ConsumeIntegralInRange<
104                                                     size_t>(0, options.extraBinders.size() - 1));
105                                 } else {
106                                     return nullptr;
107                                 }
108                             },
109                     });
110                     sp<IBinder> binder = makeFunc();
111                     CHECK(OK == p->writeStrongBinder(binder));
112                 },
113         });
114 
115         fillFunc();
116     }
117 }
118 
119 } // namespace android
120