blob: 6afea461977536f50253a15c63090c171d561414 [file] [log] [blame]
Inseob Kim15601812024-05-27 17:32:47 +09001/*
2 * Copyright 2024 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 <aidl/android/system/virtualizationservice/IVirtualizationService.h>
17#include <android-base/file.h>
18#include <android-base/result.h>
19#include <android-base/unique_fd.h>
20#include <fuzzbinder/libbinder_ndk_driver.h>
21#include <fuzzer/FuzzedDataProvider.h>
22#include <unistd.h>
23
24#include <binder_rpc_unstable.hpp>
25#include <cstdlib>
26#include <iostream>
27
28using aidl::android::system::virtualizationservice::IVirtualizationService;
29using android::fuzzService;
30using android::base::ErrnoError;
31using android::base::Error;
32using android::base::Pipe;
33using android::base::Result;
34using android::base::Socketpair;
35using android::base::unique_fd;
36using ndk::SpAIBinder;
37
38static constexpr const char VIRTMGR_PATH[] = "/apex/com.android.virt/bin/virtmgr";
39static constexpr size_t VIRTMGR_THREADS = 2;
40
41Result<unique_fd> get_service_fd() {
42 unique_fd server_fd, client_fd;
43 if (!Socketpair(SOCK_STREAM, &server_fd, &client_fd)) {
44 return ErrnoError() << "Failed to create socketpair";
45 }
46
47 unique_fd wait_fd, ready_fd;
48 if (!Pipe(&wait_fd, &ready_fd, 0)) {
49 return ErrnoError() << "Failed to create pipe";
50 }
51
52 if (int pid = fork(); pid == 0) {
53 client_fd.reset();
54 wait_fd.reset();
55
56 auto server_fd_str = std::to_string(server_fd.get());
57 auto ready_fd_str = std::to_string(ready_fd.get());
58
59 if (execl(VIRTMGR_PATH, VIRTMGR_PATH, "--rpc-server-fd", server_fd_str.c_str(),
60 "--ready-fd", ready_fd_str.c_str(), nullptr) == -1) {
61 return ErrnoError() << "Failed to execute virtmgr";
62 }
63 } else if (pid < 0) {
64 return ErrnoError() << "Failed to fork";
65 }
66
67 server_fd.reset();
68 ready_fd.reset();
69
70 char buf;
71 if (read(wait_fd.get(), &buf, sizeof(buf)) < 0) {
72 return ErrnoError() << "Failed to wait for VirtualizationService to be ready";
73 }
74
75 return client_fd;
76}
77
78Result<std::shared_ptr<IVirtualizationService>> connect_service(int fd) {
79 std::unique_ptr<ARpcSession, decltype(&ARpcSession_free)> session(ARpcSession_new(),
80 &ARpcSession_free);
81 ARpcSession_setFileDescriptorTransportMode(session.get(),
82 ARpcSession_FileDescriptorTransportMode::Unix);
83 ARpcSession_setMaxIncomingThreads(session.get(), VIRTMGR_THREADS);
84 ARpcSession_setMaxOutgoingConnections(session.get(), VIRTMGR_THREADS);
85 AIBinder* binder = ARpcSession_setupUnixDomainBootstrapClient(session.get(), fd);
86 if (binder == nullptr) {
87 return Error() << "Failed to connect to VirtualizationService";
88 }
89 return IVirtualizationService::fromBinder(SpAIBinder{binder});
90}
91
92Result<void> inner_fuzz(const uint8_t* data, size_t size) {
93 unique_fd fd = OR_RETURN(get_service_fd());
94 std::shared_ptr<IVirtualizationService> service = OR_RETURN(connect_service(fd.get()));
95 fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
96
97 return {};
98}
99
100extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
101 if (auto ret = inner_fuzz(data, size); !ret.ok()) {
102 std::cerr << "connecting to service failed: " << ret.error() << std::endl;
103 abort();
104 }
105 return 0;
106}