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