1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
|
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <android/binder_rpc.h>
#include <arpa/inet.h>
#include <binder/IServiceManager.h>
#include <linux/vm_sockets.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <variant>
#include "ibinder_internal.h"
#include "status_internal.h"
using ::android::defaultServiceManager;
using ::android::IBinder;
using ::android::IServiceManager;
using ::android::OK;
using ::android::sp;
using ::android::status_t;
using ::android::String16;
using ::android::String8;
using ::android::binder::Status;
#define LOG_ACCESSOR_DEBUG(...)
// #define LOG_ACCESSOR_DEBUG(...) ALOGW(__VA_ARGS__)
struct ABinderRpc_ConnectionInfo {
std::variant<sockaddr_vm, sockaddr_un, sockaddr_in> addr;
};
struct ABinderRpc_Accessor final : public ::android::RefBase {
static ABinderRpc_Accessor* make(const char* instance, const sp<IBinder>& binder) {
LOG_ALWAYS_FATAL_IF(binder == nullptr, "ABinderRpc_Accessor requires a non-null binder");
status_t status = android::validateAccessor(String16(instance), binder);
if (status != OK) {
ALOGE("The given binder is not a valid IAccessor for %s. Status: %s", instance,
android::statusToString(status).c_str());
return nullptr;
}
return new ABinderRpc_Accessor(binder);
}
sp<IBinder> asBinder() { return mAccessorBinder; }
~ABinderRpc_Accessor() { LOG_ACCESSOR_DEBUG("ABinderRpc_Accessor dtor"); }
private:
ABinderRpc_Accessor(sp<IBinder> accessor) : mAccessorBinder(accessor) {}
ABinderRpc_Accessor() = delete;
sp<IBinder> mAccessorBinder;
};
struct ABinderRpc_AccessorProvider {
public:
static ABinderRpc_AccessorProvider* make(std::weak_ptr<android::AccessorProvider> cookie) {
if (cookie.expired()) {
ALOGE("Null AccessorProvider cookie from libbinder");
return nullptr;
}
return new ABinderRpc_AccessorProvider(cookie);
}
std::weak_ptr<android::AccessorProvider> mProviderCookie;
private:
ABinderRpc_AccessorProvider() = delete;
ABinderRpc_AccessorProvider(std::weak_ptr<android::AccessorProvider> provider)
: mProviderCookie(provider) {}
};
struct OnDeleteProviderHolder {
OnDeleteProviderHolder(void* data, ABinderRpc_AccessorProviderUserData_deleteCallback onDelete)
: mData(data), mOnDelete(onDelete) {}
~OnDeleteProviderHolder() {
if (mOnDelete) {
mOnDelete(mData);
}
}
void* mData;
ABinderRpc_AccessorProviderUserData_deleteCallback mOnDelete;
// needs to be copy-able for std::function, but we will never copy it
OnDeleteProviderHolder(const OnDeleteProviderHolder&) {
LOG_ALWAYS_FATAL("This object can't be copied!");
}
private:
OnDeleteProviderHolder() = delete;
};
ABinderRpc_AccessorProvider* ABinderRpc_registerAccessorProvider(
ABinderRpc_AccessorProvider_getAccessorCallback provider,
const char* const* const instances, size_t numInstances, void* data,
ABinderRpc_AccessorProviderUserData_deleteCallback onDelete) {
if (data && onDelete == nullptr) {
ALOGE("If a non-null data ptr is passed to ABinderRpc_registerAccessorProvider, then a "
"ABinderRpc_AccessorProviderUserData_deleteCallback must also be passed to delete "
"the data object once the ABinderRpc_AccessorProvider is removed.");
return nullptr;
}
// call the onDelete when the last reference of this goes away (when the
// last reference to the generate std::function goes away).
std::shared_ptr<OnDeleteProviderHolder> onDeleteHolder =
std::make_shared<OnDeleteProviderHolder>(data, onDelete);
if (provider == nullptr) {
ALOGE("Null provider passed to ABinderRpc_registerAccessorProvider");
return nullptr;
}
if (numInstances == 0 || instances == nullptr) {
ALOGE("No instances passed to ABinderRpc_registerAccessorProvider. numInstances: %zu",
numInstances);
return nullptr;
}
std::set<std::string> instanceStrings;
for (size_t i = 0; i < numInstances; i++) {
instanceStrings.emplace(instances[i]);
}
android::RpcAccessorProvider generate = [provider,
onDeleteHolder](const String16& name) -> sp<IBinder> {
ABinderRpc_Accessor* accessor = provider(String8(name).c_str(), onDeleteHolder->mData);
if (accessor == nullptr) {
ALOGE("The supplied ABinderRpc_AccessorProvider_getAccessorCallback returned nullptr");
return nullptr;
}
sp<IBinder> binder = accessor->asBinder();
ABinderRpc_Accessor_delete(accessor);
return binder;
};
std::weak_ptr<android::AccessorProvider> cookie =
android::addAccessorProvider(std::move(instanceStrings), std::move(generate));
return ABinderRpc_AccessorProvider::make(cookie);
}
void ABinderRpc_unregisterAccessorProvider(ABinderRpc_AccessorProvider* provider) {
if (provider == nullptr) {
LOG_ALWAYS_FATAL("Attempting to remove a null ABinderRpc_AccessorProvider");
}
status_t status = android::removeAccessorProvider(provider->mProviderCookie);
// There shouldn't be a way to get here because the caller won't have a
// ABinderRpc_AccessorProvider* without calling ABinderRpc_registerAccessorProvider
LOG_ALWAYS_FATAL_IF(status == android::BAD_VALUE, "Provider (%p) is not valid. Status: %s",
provider, android::statusToString(status).c_str());
LOG_ALWAYS_FATAL_IF(status == android::NAME_NOT_FOUND,
"Provider (%p) was already unregistered. Status: %s", provider,
android::statusToString(status).c_str());
LOG_ALWAYS_FATAL_IF(status != OK,
"Unknown error when attempting to unregister ABinderRpc_AccessorProvider "
"(%p). Status: %s",
provider, android::statusToString(status).c_str());
delete provider;
}
struct OnDeleteConnectionInfoHolder {
OnDeleteConnectionInfoHolder(void* data,
ABinderRpc_ConnectionInfoProviderUserData_delete onDelete)
: mData(data), mOnDelete(onDelete) {}
~OnDeleteConnectionInfoHolder() {
if (mOnDelete) {
mOnDelete(mData);
}
}
void* mData;
ABinderRpc_ConnectionInfoProviderUserData_delete mOnDelete;
// needs to be copy-able for std::function, but we will never copy it
OnDeleteConnectionInfoHolder(const OnDeleteConnectionInfoHolder&) {
LOG_ALWAYS_FATAL("This object can't be copied!");
}
private:
OnDeleteConnectionInfoHolder() = delete;
};
ABinderRpc_Accessor* ABinderRpc_Accessor_new(
const char* instance, ABinderRpc_ConnectionInfoProvider provider, void* data,
ABinderRpc_ConnectionInfoProviderUserData_delete onDelete) {
if (instance == nullptr) {
ALOGE("Instance argument must be valid when calling ABinderRpc_Accessor_new");
return nullptr;
}
if (data && onDelete == nullptr) {
ALOGE("If a non-null data ptr is passed to ABinderRpc_Accessor_new, then a "
"ABinderRpc_ConnectionInfoProviderUserData_delete callback must also be passed to "
"delete "
"the data object once the ABinderRpc_Accessor is deleted.");
return nullptr;
}
std::shared_ptr<OnDeleteConnectionInfoHolder> onDeleteHolder =
std::make_shared<OnDeleteConnectionInfoHolder>(data, onDelete);
if (provider == nullptr) {
ALOGE("Can't create a new ABinderRpc_Accessor without a ABinderRpc_ConnectionInfoProvider "
"and it is "
"null");
return nullptr;
}
android::RpcSocketAddressProvider generate = [provider, onDeleteHolder](
const String16& name, sockaddr* outAddr,
size_t addrLen) -> status_t {
std::unique_ptr<ABinderRpc_ConnectionInfo> info(
provider(String8(name).c_str(), onDeleteHolder->mData));
if (info == nullptr) {
ALOGE("The supplied ABinderRpc_ConnectionInfoProvider returned nullptr");
return android::NAME_NOT_FOUND;
}
if (auto addr = std::get_if<sockaddr_vm>(&info->addr)) {
LOG_ALWAYS_FATAL_IF(addr->svm_family != AF_VSOCK,
"ABinderRpc_ConnectionInfo invalid family");
if (addrLen < sizeof(sockaddr_vm)) {
ALOGE("Provided outAddr is too small! Expecting %zu, got %zu", sizeof(sockaddr_vm),
addrLen);
return android::BAD_VALUE;
}
LOG_ACCESSOR_DEBUG(
"Connection info provider found AF_VSOCK. family %d, port %d, cid %d",
addr->svm_family, addr->svm_port, addr->svm_cid);
*reinterpret_cast<sockaddr_vm*>(outAddr) = *addr;
} else if (auto addr = std::get_if<sockaddr_un>(&info->addr)) {
LOG_ALWAYS_FATAL_IF(addr->sun_family != AF_UNIX,
"ABinderRpc_ConnectionInfo invalid family");
if (addrLen < sizeof(sockaddr_un)) {
ALOGE("Provided outAddr is too small! Expecting %zu, got %zu", sizeof(sockaddr_un),
addrLen);
return android::BAD_VALUE;
}
*reinterpret_cast<sockaddr_un*>(outAddr) = *addr;
} else if (auto addr = std::get_if<sockaddr_in>(&info->addr)) {
LOG_ALWAYS_FATAL_IF(addr->sin_family != AF_INET,
"ABinderRpc_ConnectionInfo invalid family");
if (addrLen < sizeof(sockaddr_in)) {
ALOGE("Provided outAddr is too small! Expecting %zu, got %zu", sizeof(sockaddr_in),
addrLen);
return android::BAD_VALUE;
}
*reinterpret_cast<sockaddr_in*>(outAddr) = *addr;
} else {
LOG_ALWAYS_FATAL(
"Unsupported address family type when trying to get ARpcConnection info. A "
"new variant was added to the ABinderRpc_ConnectionInfo and this needs to be "
"updated.");
}
return STATUS_OK;
};
sp<IBinder> accessorBinder = android::createAccessor(String16(instance), std::move(generate));
if (accessorBinder == nullptr) {
ALOGE("service manager did not get us an accessor");
return nullptr;
}
LOG_ACCESSOR_DEBUG("service manager found an accessor, so returning one now from _new");
return ABinderRpc_Accessor::make(instance, accessorBinder);
}
void ABinderRpc_Accessor_delete(ABinderRpc_Accessor* accessor) {
delete accessor;
}
AIBinder* ABinderRpc_Accessor_asBinder(ABinderRpc_Accessor* accessor) {
if (!accessor) {
ALOGE("ABinderRpc_Accessor argument is null.");
return nullptr;
}
sp<IBinder> binder = accessor->asBinder();
sp<AIBinder> aBinder = ABpBinder::lookupOrCreateFromBinder(binder);
AIBinder* ptr = aBinder.get();
if (ptr == nullptr) {
LOG_ALWAYS_FATAL("Failed to lookupOrCreateFromBinder");
}
ptr->incStrong(nullptr);
return ptr;
}
ABinderRpc_Accessor* ABinderRpc_Accessor_fromBinder(const char* instance, AIBinder* binder) {
if (!binder) {
ALOGE("binder argument is null");
return nullptr;
}
sp<IBinder> accessorBinder = binder->getBinder();
if (accessorBinder) {
return ABinderRpc_Accessor::make(instance, accessorBinder);
} else {
ALOGE("Attempting to get an ABinderRpc_Accessor for %s but AIBinder::getBinder returned "
"null",
instance);
return nullptr;
}
}
binder_status_t ABinderRpc_Accessor_delegateAccessor(const char* instance, AIBinder* accessor,
AIBinder** outDelegator) {
LOG_ALWAYS_FATAL_IF(outDelegator == nullptr, "The outDelegator argument is null");
if (instance == nullptr || accessor == nullptr) {
ALOGW("instance or accessor arguments to ABinderRpc_Accessor_delegateBinder are null");
*outDelegator = nullptr;
return STATUS_UNEXPECTED_NULL;
}
sp<IBinder> accessorBinder = accessor->getBinder();
sp<IBinder> delegator;
status_t status = android::delegateAccessor(String16(instance), accessorBinder, &delegator);
if (status != OK) {
return PruneStatusT(status);
}
sp<AIBinder> binder = ABpBinder::lookupOrCreateFromBinder(delegator);
// This AIBinder needs a strong ref to pass ownership to the caller
binder->incStrong(nullptr);
*outDelegator = binder.get();
return STATUS_OK;
}
ABinderRpc_ConnectionInfo* ABinderRpc_ConnectionInfo_new(const sockaddr* addr, socklen_t len) {
if (addr == nullptr || len < 0 || static_cast<size_t>(len) < sizeof(sa_family_t)) {
ALOGE("Invalid arguments in ABinderRpc_Connection_new");
return nullptr;
}
// socklen_t was int32_t on 32-bit and uint32_t on 64 bit.
size_t socklen = len < 0 || static_cast<uintmax_t>(len) > SIZE_MAX ? 0 : len;
if (addr->sa_family == AF_VSOCK) {
if (len != sizeof(sockaddr_vm)) {
ALOGE("Incorrect size of %zu for AF_VSOCK sockaddr_vm. Expecting %zu", socklen,
sizeof(sockaddr_vm));
return nullptr;
}
sockaddr_vm vm = *reinterpret_cast<const sockaddr_vm*>(addr);
LOG_ACCESSOR_DEBUG(
"ABinderRpc_ConnectionInfo_new found AF_VSOCK. family %d, port %d, cid %d",
vm.svm_family, vm.svm_port, vm.svm_cid);
return new ABinderRpc_ConnectionInfo(vm);
} else if (addr->sa_family == AF_UNIX) {
if (len != sizeof(sockaddr_un)) {
ALOGE("Incorrect size of %zu for AF_UNIX sockaddr_un. Expecting %zu", socklen,
sizeof(sockaddr_un));
return nullptr;
}
sockaddr_un un = *reinterpret_cast<const sockaddr_un*>(addr);
LOG_ACCESSOR_DEBUG("ABinderRpc_ConnectionInfo_new found AF_UNIX. family %d, path %s",
un.sun_family, un.sun_path);
return new ABinderRpc_ConnectionInfo(un);
} else if (addr->sa_family == AF_INET) {
if (len != sizeof(sockaddr_in)) {
ALOGE("Incorrect size of %zu for AF_INET sockaddr_in. Expecting %zu", socklen,
sizeof(sockaddr_in));
return nullptr;
}
sockaddr_in in = *reinterpret_cast<const sockaddr_in*>(addr);
LOG_ACCESSOR_DEBUG(
"ABinderRpc_ConnectionInfo_new found AF_INET. family %d, address %s, port %d",
in.sin_family, inet_ntoa(in.sin_addr), ntohs(in.sin_port));
return new ABinderRpc_ConnectionInfo(in);
}
ALOGE("ABinderRpc APIs only support AF_VSOCK right now but the supplied sockaddr::sa_family "
"is: %hu",
addr->sa_family);
return nullptr;
}
void ABinderRpc_ConnectionInfo_delete(ABinderRpc_ConnectionInfo* info) {
delete info;
}
|