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_fd.h>
18
19 #include <fcntl.h>
20
21 #include <android-base/logging.h>
22 #include <cutils/ashmem.h>
23
24 namespace android {
25
26 using binder::unique_fd;
27
getRandomFds(FuzzedDataProvider * provider)28 std::vector<unique_fd> getRandomFds(FuzzedDataProvider* provider) {
29 const char* fdType;
30
31 std::vector<unique_fd> fds = provider->PickValueInArray<
32 std::function<std::vector<unique_fd>()>>(
33 {[&]() {
34 fdType = "ashmem";
35 std::vector<unique_fd> ret;
36 ret.push_back(unique_fd(
37 ashmem_create_region("binder test region",
38 provider->ConsumeIntegralInRange<size_t>(0, 4096))));
39 return ret;
40 },
41 [&]() {
42 fdType = "/dev/null";
43 std::vector<unique_fd> ret;
44 ret.push_back(unique_fd(open("/dev/null", O_RDWR)));
45 return ret;
46 },
47 [&]() {
48 fdType = "pipefd";
49
50 int pipefds[2];
51
52 int flags = O_CLOEXEC;
53 if (provider->ConsumeBool()) flags |= O_DIRECT;
54
55 // TODO(b/236812909): also test blocking
56 if (true) flags |= O_NONBLOCK;
57
58 CHECK_EQ(0, pipe2(pipefds, flags)) << flags;
59
60 if (provider->ConsumeBool()) std::swap(pipefds[0], pipefds[1]);
61
62 std::vector<unique_fd> ret;
63 ret.push_back(unique_fd(pipefds[0]));
64 ret.push_back(unique_fd(pipefds[1]));
65 return ret;
66 },
67 [&]() {
68 fdType = "tempfd";
69 char name[PATH_MAX];
70 #if defined(__ANDROID__)
71 snprintf(name, sizeof(name), "/data/local/tmp/android-tempfd-test-%d-XXXXXX",
72 getpid());
73 #else
74 snprintf(name, sizeof(name), "/tmp/android-tempfd-test-%d-XXXXXX", getpid());
75 #endif
76 int fd = mkstemp(name);
77 CHECK_NE(fd, -1) << "Failed to create file " << name << ", errno: " << errno;
78 unlink(name);
79 if (provider->ConsumeBool()) {
80 CHECK_NE(TEMP_FAILURE_RETRY(
81 ftruncate(fd,
82 provider->ConsumeIntegralInRange<size_t>(0, 4096))),
83 -1)
84 << "Failed to truncate file, errno: " << errno;
85 }
86
87 std::vector<unique_fd> ret;
88 ret.push_back(unique_fd(fd));
89 return ret;
90 }
91
92 })();
93
94 for (const auto& fd : fds) CHECK(fd.ok()) << fd.get() << " " << fdType;
95
96 return fds;
97 }
98
99 } // namespace android
100