• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 #ifndef FRAMEWORKS_BASE_CORE_JNI_FD_UTILS_H_
18 #define FRAMEWORKS_BASE_CORE_JNI_FD_UTILS_H_
19 
20 #include <set>
21 #include <string>
22 #include <unordered_map>
23 #include <vector>
24 
25 #include <dirent.h>
26 #include <inttypes.h>
27 #include <sys/stat.h>
28 
29 #include <android-base/macros.h>
30 
31 // Whitelist of open paths that the zygote is allowed to keep open.
32 //
33 // In addition to the paths listed in kPathWhitelist in file_utils.cpp, and
34 // paths dynamically added with Allow(), all files ending with ".jar"
35 // under /system/framework" are whitelisted. See IsAllowed() for the canonical
36 // definition.
37 //
38 // If the whitelisted path is associated with a regular file or a
39 // character device, the file is reopened after a fork with the same
40 // offset and mode. If the whilelisted  path is associated with a
41 // AF_UNIX socket, the socket will refer to /dev/null after each
42 // fork, and all operations on it will fail.
43 class FileDescriptorWhitelist {
44  public:
45   // Lazily creates the global whitelist.
46   static FileDescriptorWhitelist* Get();
47 
48   // Adds a path to the whitelist.
Allow(const std::string & path)49   void Allow(const std::string& path) {
50     whitelist_.push_back(path);
51   }
52 
53   // Returns true iff. a given path is whitelisted. A path is whitelisted
54   // if it belongs to the whitelist (see kPathWhitelist) or if it's a path
55   // under /system/framework that ends with ".jar" or if it is a system
56   // framework overlay.
57   bool IsAllowed(const std::string& path) const;
58 
59  private:
60   FileDescriptorWhitelist();
61 
62   static FileDescriptorWhitelist* instance_;
63 
64   std::vector<std::string> whitelist_;
65 
66   DISALLOW_COPY_AND_ASSIGN(FileDescriptorWhitelist);
67 };
68 
69 // Keeps track of all relevant information (flags, offset etc.) of an
70 // open zygote file descriptor.
71 class FileDescriptorInfo {
72  public:
73   // Create a FileDescriptorInfo for a given file descriptor. Returns
74   // |NULL| if an error occurred.
75   static FileDescriptorInfo* CreateFromFd(int fd);
76 
77   // Checks whether the file descriptor associated with this object
78   // refers to the same description.
79   bool Restat() const;
80 
81   bool ReopenOrDetach() const;
82 
83   const int fd;
84   const struct stat stat;
85   const std::string file_path;
86   const int open_flags;
87   const int fd_flags;
88   const int fs_flags;
89   const off_t offset;
90   const bool is_sock;
91 
92  private:
93   FileDescriptorInfo(int fd);
94 
95   FileDescriptorInfo(struct stat stat, const std::string& file_path, int fd, int open_flags,
96                      int fd_flags, int fs_flags, off_t offset);
97 
98   // Returns the locally-bound name of the socket |fd|. Returns true
99   // iff. all of the following hold :
100   //
101   // - the socket's sa_family is AF_UNIX.
102   // - the length of the path is greater than zero (i.e, not an unnamed socket).
103   // - the first byte of the path isn't zero (i.e, not a socket with an abstract
104   //   address).
105   static bool GetSocketName(const int fd, std::string* result);
106 
107   bool DetachSocket() const;
108 
109   DISALLOW_COPY_AND_ASSIGN(FileDescriptorInfo);
110 };
111 
112 // A FileDescriptorTable is a collection of FileDescriptorInfo objects
113 // keyed by their FDs.
114 class FileDescriptorTable {
115  public:
116   // Creates a new FileDescriptorTable. This function scans
117   // /proc/self/fd for the list of open file descriptors and collects
118   // information about them. Returns NULL if an error occurs.
119   static FileDescriptorTable* Create(const std::vector<int>& fds_to_ignore);
120 
121   bool Restat(const std::vector<int>& fds_to_ignore);
122 
123   // Reopens all file descriptors that are contained in the table. Returns true
124   // if all descriptors were successfully re-opened or detached, and false if an
125   // error occurred.
126   bool ReopenOrDetach();
127 
128  private:
129   FileDescriptorTable(const std::unordered_map<int, FileDescriptorInfo*>& map);
130 
131   bool RestatInternal(std::set<int>& open_fds);
132 
133   static int ParseFd(dirent* e, int dir_fd);
134 
135   // Invariant: All values in this unordered_map are non-NULL.
136   std::unordered_map<int, FileDescriptorInfo*> open_fd_map_;
137 
138   DISALLOW_COPY_AND_ASSIGN(FileDescriptorTable);
139 };
140 
141 #endif  // FRAMEWORKS_BASE_CORE_JNI_FD_UTILS_H_
142