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