• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // The sandbox2::util namespace provides various, uncategorized, functions
16 // useful for creating sandboxes.
17 
18 #ifndef SANDBOXED_API_SANDBOX2_UTIL_H_
19 #define SANDBOXED_API_SANDBOX2_UTIL_H_
20 
21 #include <sys/types.h>
22 
23 #include <cstddef>
24 #include <cstdint>
25 #include <string>
26 #include <vector>
27 
28 #include "absl/base/macros.h"
29 #include "absl/status/statusor.h"
30 #include "absl/types/span.h"
31 
32 namespace sandbox2 {
33 
34 namespace internal {
35 
36 // Magic values used to detect if the current process is running inside
37 // Sandbox2.
38 inline constexpr int64_t kMagicSyscallNo = 0xff000fdb;  // 4278194139
39 inline constexpr int kMagicSyscallErr = 0x000000fdb;    // 4059
40 
41 }  // namespace internal
42 
43 namespace util {
44 
45 void DumpCoverageData();
46 
47 // An char ptr array limited by the terminating nullptr entry (like environ
48 // or argv).
49 class CharPtrArray {
50  public:
51   CharPtrArray(char* const* array);
52   static CharPtrArray FromStringVector(const std::vector<std::string>& vec);
53 
array()54   const std::vector<const char*>& array() const { return array_; }
55 
data()56   const char* const* data() const { return array_.data(); }
57 
58   std::vector<std::string> ToStringVector() const;
59 
60  private:
61   CharPtrArray(const std::vector<std::string>& vec);
62 
63   const std::string content_;
64   std::vector<const char*> array_;
65 };
66 
67 // Converts an array of char* (terminated by a nullptr, like argv, or environ
68 // arrays), to an std::vector<std::string>.
ABSL_DEPRECATE_AND_INLINE()69 ABSL_DEPRECATE_AND_INLINE()
70 inline void CharPtrArrToVecString(char* const* arr,
71                                   std::vector<std::string>* vec) {
72   *vec = sandbox2::util::CharPtrArray(arr).ToStringVector();
73 }
74 
75 // Returns the program name (via /proc/self/comm) for a given PID.
76 std::string GetProgName(pid_t pid);
77 
78 // Given a resource descriptor FD and a PID, returns link of /proc/PID/fds/FD.
79 absl::StatusOr<std::string> GetResolvedFdLink(pid_t pid, uint32_t fd);
80 
81 // Returns the command line (via /proc/self/cmdline) for a given PID. The
82 // argument separators '\0' are converted to spaces.
83 std::string GetCmdLine(pid_t pid);
84 
85 // Returns the specified line from /proc/<pid>/status for a given PID. 'value'
86 // is a field name like "Threads" or "Tgid".
87 std::string GetProcStatusLine(int pid, const std::string& value);
88 
89 // Invokes a syscall, avoiding on-stack argument promotion, as it might happen
90 // with vararg syscall() function.
91 long Syscall(long sys_no,  // NOLINT
92              uintptr_t a1 = 0, uintptr_t a2 = 0, uintptr_t a3 = 0,
93              uintptr_t a4 = 0, uintptr_t a5 = 0, uintptr_t a6 = 0);
94 
95 // Fork based on clone() which updates glibc's PID/TID caches - Based on:
96 // https://chromium.googlesource.com/chromium/src/+/9eb564175dbd452196f782da2b28e3e8e79c49a5%5E!/
97 //
98 // Return values as for 'man 2 fork'.
99 pid_t ForkWithFlags(int flags);
100 
101 // Creates a new memfd.
102 bool CreateMemFd(int* fd, const char* name = "buffer_file");
103 
104 // Executes a the program given by argv and the specified environment and
105 // captures any output to stdout/stderr.
106 absl::StatusOr<int> Communicate(const std::vector<std::string>& argv,
107                                 const std::vector<std::string>& envv,
108                                 std::string* output);
109 
110 // Returns signal description.
111 std::string GetSignalName(int signo);
112 
113 // Returns the socket address family as a string ("AF_INET", ...)
114 std::string GetAddressFamily(int addr_family);
115 
116 // Returns rlimit resource name
117 std::string GetRlimitName(int resource);
118 
119 // Returns ptrace event name
120 std::string GetPtraceEventName(int event);
121 
122 namespace internal {
123 // Reads `data`'s length of bytes from `ptr` in `pid`, returns number of bytes
124 // read or an error.
125 absl::StatusOr<size_t> ReadBytesFromPidWithReadv(pid_t pid, uintptr_t ptr,
126                                                  absl::Span<char> data);
127 
128 // Writes `data` to `ptr` in `pid`, returns number of bytes written or an error.
129 absl::StatusOr<size_t> WriteBytesToPidWithWritev(pid_t pid, uintptr_t ptr,
130                                                  absl::Span<const char> data);
131 
132 // Reads `data`'s length of bytes from `ptr` in `pid`, returns number of bytes
133 // read or an error.
134 absl::StatusOr<size_t> ReadBytesFromPidWithReadvInSplitChunks(
135     pid_t pid, uintptr_t ptr, absl::Span<char> data);
136 
137 // Reads `data`'s length of bytes from `ptr` in `pid`, returns number of bytes
138 // read or an error.
139 absl::StatusOr<size_t> ReadBytesFromPidWithProcMem(pid_t pid, uintptr_t ptr,
140                                                    absl::Span<char> data);
141 
142 // Writes `data` to `ptr` in `pid`, returns number of bytes written or an error.
143 absl::StatusOr<size_t> WriteBytesToPidWithProcMem(pid_t pid, uintptr_t ptr,
144                                                   absl::Span<const char> data);
145 };  // namespace internal
146 
147 // Reads `data`'s length of bytes from `ptr` in `pid`, returns number of bytes
148 // read or an error.
149 absl::StatusOr<size_t> ReadBytesFromPidInto(pid_t pid, uintptr_t ptr,
150                                             absl::Span<char> data);
151 
152 // Writes `data` to `ptr` in `pid`, returns number of bytes written or an error.
153 absl::StatusOr<size_t> WriteBytesToPidFrom(pid_t pid, uintptr_t remote_ptr,
154                                            absl::Span<const char> data);
155 
156 // Reads `size` bytes from the given `ptr` address, or returns an error.
157 absl::StatusOr<std::vector<uint8_t>> ReadBytesFromPid(pid_t pid, uintptr_t ptr,
158                                                       size_t size);
159 
160 // Reads a path string (NUL-terminated, shorter than PATH_MAX) from another
161 // process memory
162 absl::StatusOr<std::string> ReadCPathFromPid(pid_t pid, uintptr_t ptr);
163 
164 // Wrapper for execveat(2).
165 int Execveat(int dirfd, const char* pathname, const char* const argv[],
166              const char* const envp[], int flags, uintptr_t extra_arg = 0);
167 
168 // Returns true if the current process is running inside Sandbox2.
169 absl::StatusOr<bool> IsRunningInSandbox2();
170 
171 }  // namespace util
172 }  // namespace sandbox2
173 
174 #endif  // SANDBOXED_API_SANDBOX2_UTIL_H_
175