1 /*
2 * Copyright (C) 2021-2024 Huawei Device Co., Ltd.
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 * http://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
16 #include "binder_connector.h"
17
18 #include <cinttypes>
19 #include <cstdint>
20 #include <fcntl.h>
21 #include <sys/ioctl.h>
22 #include <sys/mman.h>
23 #ifdef CONFIG_ACTV_BINDER
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #endif
27 #include <unistd.h>
28
29 #include "__mutex_base"
30 #include "cerrno"
31 #include "hilog/log_c.h"
32 #include "hilog/log_cpp.h"
33 #include "iosfwd"
34 #include "ipc_debug.h"
35 #include "ipc_types.h"
36 #include "log_tags.h"
37 #include "new"
38 #include "string"
39 #include "sys_binder.h"
40 #ifdef CONFIG_ACTV_BINDER
41 #include "actv_binder.h"
42 #endif
43
44 namespace OHOS {
45 static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC_BINDER_CONNECT, "BinderConnector" };
46 std::mutex BinderConnector::skeletonMutex;
47 constexpr int SZ_1_M = 1048576;
48 constexpr int DOUBLE = 2;
49 static const int IPC_MMAP_SIZE = (SZ_1_M - sysconf(_SC_PAGE_SIZE) * DOUBLE);
50 static constexpr const char *DRIVER_NAME = "/dev/binder";
51 static constexpr const char *TOKENID_DEVNODE = "/dev/access_token_id";
52 BinderConnector *BinderConnector::instance_ = nullptr;
53
BinderConnector(const std::string & deviceName)54 BinderConnector::BinderConnector(const std::string &deviceName)
55 : driverFD_(-1), vmAddr_(MAP_FAILED), deviceName_(deviceName), version_(0), featureSet_(0), selfTokenID_(0)
56 {}
57
~BinderConnector()58 BinderConnector::~BinderConnector()
59 {
60 if (vmAddr_ != MAP_FAILED) {
61 munmap(vmAddr_, IPC_MMAP_SIZE);
62 vmAddr_ = MAP_FAILED;
63 }
64
65 CloseDriverFd();
66 };
67
IsDriverAlive()68 bool BinderConnector::IsDriverAlive()
69 {
70 return driverFD_ >= 0;
71 }
72
73 #ifdef CONFIG_ACTV_BINDER
ActvBinderConnector()74 ActvBinderConnector::ActvBinderConnector()
75 : isActvMgr_(false)
76 {
77 }
78
InitActvBinder(int fd)79 int ActvBinderConnector::InitActvBinder(int fd)
80 {
81 if (!isActvMgr_) {
82 return 0;
83 }
84
85 int ret;
86 uint64_t poolCref;
87
88 ret = ioctl(fd, BINDER_SET_ACTVMGR, &poolCref);
89 if (ret != 0) {
90 ZLOGE(LABEL, "ActvBinder: set actv binder service failed, errno: %{public}d", errno);
91 return ret;
92 }
93
94 return 0;
95 }
96
InitActvBinderConfig(uint64_t featureSet)97 void ActvBinderConnector::InitActvBinderConfig(uint64_t featureSet)
98 {
99 if ((featureSet & ACTV_BINDER_FEATURE_MASK) == 0) {
100 return;
101 }
102
103 struct stat stat_unused;
104 /* If there is ACTV_BINDER_SERVICES_CONFIG, set actvmgr for actv binder */
105 if (stat(ACTV_BINDER_SERVICES_CONFIG, &stat_unused) == 0) {
106 isActvMgr_ = true;
107 }
108 }
109 #endif // CONFIG_ACTV_BINDER
110
OpenDriver()111 bool BinderConnector::OpenDriver()
112 {
113 int fd = open(deviceName_.c_str(), O_RDWR | O_CLOEXEC);
114 if (fd < 0) {
115 ZLOGE(LABEL, "fail to open errno:%{public}d", errno);
116 return false;
117 }
118 int32_t version = 0;
119 int ret = ioctl(fd, BINDER_VERSION, &version);
120 if (ret != 0 || version != BINDER_CURRENT_PROTOCOL_VERSION) {
121 ZLOGE(LABEL, "Get Binder version failed, error:%{public}d "
122 "or version not match, driver version:%{public}d, ipc version:%{public}d",
123 errno, version, BINDER_CURRENT_PROTOCOL_VERSION);
124 close(fd);
125 return false;
126 }
127 uint64_t featureSet = 0;
128 ret = ioctl(fd, BINDER_FEATURE_SET, &featureSet);
129 if (ret != 0) {
130 ZLOGE(LABEL, "Get Binder featureSet failed:%{public}d, disable all enhance feature.", errno);
131 featureSet = 0;
132 }
133 ZLOGD(LABEL, "success to open fd:%{public}d", fd);
134 driverFD_ = fd;
135
136 if (!MapMemory(featureSet)) {
137 close(driverFD_);
138 driverFD_ = -1;
139 return false;
140 }
141 version_ = version;
142 featureSet_ = featureSet;
143 return true;
144 }
145
MapMemory(uint64_t featureSet)146 bool BinderConnector::MapMemory(uint64_t featureSet)
147 {
148 #ifdef CONFIG_ACTV_BINDER
149 actvBinder_.InitActvBinderConfig(featureSet);
150 #endif
151
152 vmAddr_ = mmap(0, IPC_MMAP_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, driverFD_, 0);
153 if (vmAddr_ == MAP_FAILED) {
154 ZLOGE(LABEL, "fail to mmap");
155 return false;
156 }
157 #ifdef CONFIG_ACTV_BINDER
158 int ret = actvBinder_.InitActvBinder(driverFD_);
159 if (ret != 0) {
160 munmap(vmAddr_, IPC_MMAP_SIZE);
161 vmAddr_ = MAP_FAILED;
162 return false;
163 }
164 #endif
165 return true;
166 }
167
IsAccessTokenSupported()168 bool BinderConnector::IsAccessTokenSupported()
169 {
170 if (IsDriverAlive() != true) {
171 return false;
172 }
173 return (featureSet_ & ACCESS_TOKEN_FAETURE_MASK) != 0;
174 }
175
IsRealPidSupported()176 bool BinderConnector::IsRealPidSupported()
177 {
178 return (featureSet_ & SENDER_INFO_FAETURE_MASK) != 0;
179 }
180 #ifdef CONFIG_ACTV_BINDER
IsActvBinderSupported()181 bool BinderConnector::IsActvBinderSupported()
182 {
183 return (IsDriverAlive() && ((featureSet_ & ACTV_BINDER_FEATURE_MASK) != 0));
184 }
185
IsActvBinderService()186 bool BinderConnector::IsActvBinderService()
187 {
188 return (IsDriverAlive() && actvBinder_.isActvMgr_);
189 }
190 #endif
191
WriteBinder(unsigned long request,void * value)192 int BinderConnector::WriteBinder(unsigned long request, void *value)
193 {
194 int err = -EINTR;
195
196 while (err == -EINTR) {
197 if (driverFD_ < 0) {
198 return -EBADF;
199 }
200 if (ioctl(driverFD_, request, value) >= 0) {
201 err = ERR_NONE;
202 } else {
203 err = -errno;
204 }
205
206 if (err == -EINTR) {
207 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
208 std::chrono::steady_clock::now().time_since_epoch()).count());
209 ZLOGW(LABEL, "ioctl_binder returned EINTR time:%{public}" PRIu64, curTime);
210 }
211 }
212
213 return err;
214 }
215
ExitCurrentThread(unsigned long request)216 void BinderConnector::ExitCurrentThread(unsigned long request)
217 {
218 if (driverFD_ > 0) {
219 ioctl(driverFD_, request, 0);
220 }
221 }
222
GetSelfTokenID()223 uint64_t BinderConnector::GetSelfTokenID()
224 {
225 if (IsAccessTokenSupported() != true) {
226 return 0;
227 }
228 int fd = open(TOKENID_DEVNODE, O_RDWR);
229 if (fd < 0) {
230 ZLOGE(LABEL, "fail to open tokenId node, errno:%{public}d", errno);
231 return 0;
232 }
233 int ret = ioctl(fd, ACCESS_TOKENID_GET_TOKENID, &selfTokenID_);
234 if (ret != 0) {
235 selfTokenID_ = 0;
236 }
237 close(fd);
238 return selfTokenID_;
239 }
240
GetSelfFirstCallerTokenID()241 uint64_t BinderConnector::GetSelfFirstCallerTokenID()
242 {
243 if (IsAccessTokenSupported() != true) {
244 return 0;
245 }
246 int fd = open(TOKENID_DEVNODE, O_RDWR);
247 if (fd < 0) {
248 ZLOGE(LABEL, "fail to open tokenId node, errno:%{public}d", errno);
249 return 0;
250 }
251 uint64_t token = 0;
252 int ret = ioctl(fd, ACCESS_TOKENID_GET_FTOKENID, &token);
253 if (ret != 0) {
254 token = 0;
255 }
256 close(fd);
257 return token;
258 }
259
CloseDriverFd()260 void BinderConnector::CloseDriverFd()
261 {
262 if (driverFD_ >= 0) {
263 int tmpFd = driverFD_;
264 driverFD_ = -1;
265 close(tmpFd);
266 }
267 }
268
GetInstance()269 BinderConnector *BinderConnector::GetInstance()
270 {
271 if (instance_ == nullptr) {
272 std::lock_guard<std::mutex> lockGuard(skeletonMutex);
273 if (instance_ == nullptr) {
274 auto temp = new (std::nothrow) BinderConnector(std::string(DRIVER_NAME));
275 if (temp == nullptr) {
276 ZLOGE(LABEL, "create BinderConnector object failed");
277 return nullptr;
278 }
279 if (!temp->OpenDriver()) {
280 delete temp;
281 temp = nullptr;
282 }
283 instance_ = temp;
284 }
285 }
286
287 return instance_;
288 }
289 } // namespace OHOS
290