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