• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 <BnTestService.h>
18 #include <fuzzbinder/libbinder_driver.h>
19 
20 #include <binder/IPCThreadState.h>
21 #include <log/log.h>
22 
23 #include <private/android_filesystem_config.h>
24 
25 using android::binder::Status;
26 
27 namespace android {
28 
29 enum class CrashType {
30     NONE,
31     ON_PLAIN,
32     ON_BINDER,
33     ON_KNOWN_UID,
34     ON_SYSTEM_AID,
35     ON_ROOT_AID,
36     ON_DUMP_TRANSACT,
37     ON_SHELL_CMD_TRANSACT,
38     CRASH_ALWAYS,
39 };
40 
41 // This service is to verify that fuzzService is functioning properly
42 class TestService : public BnTestService {
43 public:
TestService(CrashType crash)44     TestService(CrashType crash) : mCrash(crash) {}
45 
onData()46     void onData() {
47         switch (mCrash) {
48             case CrashType::ON_PLAIN: {
49                 LOG_ALWAYS_FATAL("Expected crash, PLAIN.");
50                 break;
51             }
52             case CrashType::ON_KNOWN_UID: {
53                 if (IPCThreadState::self()->getCallingUid() == getuid()) {
54                     LOG_ALWAYS_FATAL("Expected crash, KNOWN_UID.");
55                 }
56                 break;
57             }
58             case CrashType::ON_SYSTEM_AID: {
59                 if (IPCThreadState::self()->getCallingUid() == AID_SYSTEM) {
60                     LOG_ALWAYS_FATAL("Expected crash, AID_SYSTEM.");
61                 }
62                 break;
63             }
64             case CrashType::ON_ROOT_AID: {
65                 if (IPCThreadState::self()->getCallingUid() == AID_ROOT) {
66                     LOG_ALWAYS_FATAL("Expected crash, AID_ROOT.");
67                 }
68                 break;
69             }
70             default:
71                 break;
72         }
73     }
74 
setIntData(int)75     Status setIntData(int /*input*/) override {
76         onData();
77         return Status::ok();
78     }
79 
setCharData(char16_t)80     Status setCharData(char16_t /*input*/) override {
81         onData();
82         return Status::ok();
83     }
84 
setBooleanData(bool)85     Status setBooleanData(bool /*input*/) override {
86         onData();
87         return Status::ok();
88     }
89 
setService(const sp<ITestService> & service)90     Status setService(const sp<ITestService>& service) override {
91         onData();
92         if (mCrash == CrashType::ON_BINDER && service != nullptr) {
93             LOG_ALWAYS_FATAL("Expected crash, BINDER.");
94         }
95         return Status::ok();
96     }
97 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)98     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override {
99         if (mCrash == CrashType::ON_DUMP_TRANSACT && code == DUMP_TRANSACTION) {
100             LOG_ALWAYS_FATAL("Expected crash, DUMP.");
101         } else if (mCrash == CrashType::ON_SHELL_CMD_TRANSACT &&
102                    code == SHELL_COMMAND_TRANSACTION) {
103             LOG_ALWAYS_FATAL("Expected crash, SHELL_CMD.");
104         }
105         return BnTestService::onTransact(code, data, reply, flags);
106     }
107 
108 private:
109     CrashType mCrash;
110 };
111 
112 CrashType gCrashType = CrashType::NONE;
113 
LLVMFuzzerInitialize(int * argc,char *** argv)114 extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
115     if (*argc < 2) {
116         // This fuzzer is also used as test fuzzer to check infra pipeline.
117         // It should always run and find a crash in TestService.
118         gCrashType = CrashType::CRASH_ALWAYS;
119         return 0;
120     }
121 
122     std::string arg = std::string((*argv)[1]);
123 
124     // ignore first argument, because we consume it
125     (*argv)[1] = (*argv[0]);
126     (*argc)--;
127     (*argv)++;
128 
129     if (arg == "PLAIN") {
130         gCrashType = CrashType::ON_PLAIN;
131     } else if (arg == "KNOWN_UID") {
132         gCrashType = CrashType::ON_KNOWN_UID;
133     } else if (arg == "AID_SYSTEM") {
134         gCrashType = CrashType::ON_SYSTEM_AID;
135     } else if (arg == "AID_ROOT") {
136         gCrashType = CrashType::ON_ROOT_AID;
137     } else if (arg == "BINDER") {
138         gCrashType = CrashType::ON_BINDER;
139     } else if (arg == "DUMP") {
140         gCrashType = CrashType::ON_DUMP_TRANSACT;
141     } else if (arg == "SHELL_CMD") {
142         gCrashType = CrashType::ON_SHELL_CMD_TRANSACT;
143     } else {
144         printf("INVALID ARG\n");
145         exit(0); // success because this is a crash test
146     }
147 
148     return 0;
149 }
150 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)151 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
152     if (gCrashType == CrashType::CRASH_ALWAYS) {
153         LOG_ALWAYS_FATAL("Expected crash, This fuzzer will always crash.");
154     }
155     auto service = sp<TestService>::make(gCrashType);
156     fuzzService(service, FuzzedDataProvider(data, size));
157     return 0;
158 }
159 
160 } // namespace android
161