• 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_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