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 use crate::binder::AsNative;
18 use crate::error::{status_result, Result};
19 use crate::proxy::SpIBinder;
20 use crate::sys;
21
22 use std::ffi::{c_void, CStr, CString};
23 use std::os::raw::c_char;
24
25 use libc::{sockaddr, sockaddr_un, sockaddr_vm, socklen_t};
26 use std::sync::Arc;
27 use std::{fmt, mem, ptr};
28
29 /// Rust wrapper around ABinderRpc_Accessor objects for RPC binder service management.
30 ///
31 /// Dropping the `Accessor` will drop the underlying object and the binder it owns.
32 pub struct Accessor {
33 accessor: *mut sys::ABinderRpc_Accessor,
34 }
35
36 impl fmt::Debug for Accessor {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 write!(f, "ABinderRpc_Accessor({:p})", self.accessor)
39 }
40 }
41
42 /// Socket connection info required for libbinder to connect to a service.
43 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
44 pub enum ConnectionInfo {
45 /// For vsock connection
46 Vsock(sockaddr_vm),
47 /// For unix domain socket connection
48 Unix(sockaddr_un),
49 }
50
51 /// Safety: A `Accessor` is a wrapper around `ABinderRpc_Accessor` which is
52 /// `Sync` and `Send`. As
53 /// `ABinderRpc_Accessor` is threadsafe, this structure is too.
54 /// The Fn owned the Accessor has `Sync` and `Send` properties
55 unsafe impl Send for Accessor {}
56
57 /// Safety: A `Accessor` is a wrapper around `ABinderRpc_Accessor` which is
58 /// `Sync` and `Send`. As `ABinderRpc_Accessor` is threadsafe, this structure is too.
59 /// The Fn owned the Accessor has `Sync` and `Send` properties
60 unsafe impl Sync for Accessor {}
61
62 impl Accessor {
63 /// Create a new accessor that will call the given callback when its
64 /// connection info is required.
65 /// The callback object and all objects it captures are owned by the Accessor
66 /// and will be deleted some time after the Accessor is Dropped. If the callback
67 /// is being called when the Accessor is Dropped, the callback will not be deleted
68 /// immediately.
new<F>(instance: &str, callback: F) -> Accessor where F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static,69 pub fn new<F>(instance: &str, callback: F) -> Accessor
70 where
71 F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static,
72 {
73 let callback: *mut c_void = Arc::into_raw(Arc::new(callback)) as *mut c_void;
74 let inst = CString::new(instance).unwrap();
75
76 // Safety: The function pointer is a valid connection_info callback.
77 // This call returns an owned `ABinderRpc_Accessor` pointer which
78 // must be destroyed via `ABinderRpc_Accessor_delete` when no longer
79 // needed.
80 // When the underlying ABinderRpc_Accessor is deleted, it will call
81 // the cookie_decr_refcount callback to release its strong ref.
82 let accessor = unsafe {
83 sys::ABinderRpc_Accessor_new(
84 inst.as_ptr(),
85 Some(Self::connection_info::<F>),
86 callback,
87 Some(Self::cookie_decr_refcount::<F>),
88 )
89 };
90
91 Accessor { accessor }
92 }
93
94 /// Creates a new Accessor instance based on an existing Accessor's binder.
95 /// This is useful when the Accessor instance is hosted in another process
96 /// that has the permissions to create the socket connection FD.
97 ///
98 /// The `instance` argument must match the instance that the original Accessor
99 /// is responsible for.
100 /// `instance` must not contain null bytes and is used to create a CString to
101 /// pass through FFI.
102 /// The `binder` argument must be a valid binder from an Accessor
from_binder(instance: &str, binder: SpIBinder) -> Option<Accessor>103 pub fn from_binder(instance: &str, binder: SpIBinder) -> Option<Accessor> {
104 let inst = CString::new(instance).unwrap();
105
106 // Safety: All `SpIBinder` objects (the `binder` argument) hold a valid pointer
107 // to an `AIBinder` that is guaranteed to remain valid for the lifetime of the
108 // SpIBinder. `ABinderRpc_Accessor_fromBinder` creates a new pointer to that binder
109 // that it is responsible for.
110 // The `inst` argument is a new CString that will copied by
111 // `ABinderRpc_Accessor_fromBinder` and not modified.
112 let accessor =
113 unsafe { sys::ABinderRpc_Accessor_fromBinder(inst.as_ptr(), binder.as_raw()) };
114 if accessor.is_null() {
115 return None;
116 }
117 Some(Accessor { accessor })
118 }
119
120 /// Get the underlying binder for this Accessor for when it needs to be either
121 /// registered with service manager or sent to another process.
as_binder(&self) -> Option<SpIBinder>122 pub fn as_binder(&self) -> Option<SpIBinder> {
123 // Safety: `ABinderRpc_Accessor_asBinder` returns either a null pointer or a
124 // valid pointer to an owned `AIBinder`. Either of these values is safe to
125 // pass to `SpIBinder::from_raw`.
126 unsafe { SpIBinder::from_raw(sys::ABinderRpc_Accessor_asBinder(self.accessor)) }
127 }
128
129 /// Release the underlying ABinderRpc_Accessor pointer for use with the ndk API
130 /// This gives up ownership of the ABinderRpc_Accessor and it is the responsibility of
131 /// the caller to delete it with ABinderRpc_Accessor_delete
132 ///
133 /// # Safety
134 ///
135 /// - The returned `ABinderRpc_Accessor` pointer is now owned by the caller, who must
136 /// call `ABinderRpc_Accessor_delete` to delete the object.
137 /// - This `Accessor` object is now useless after `release` so it can be dropped.
release(mut self) -> *mut sys::ABinderRpc_Accessor138 unsafe fn release(mut self) -> *mut sys::ABinderRpc_Accessor {
139 if self.accessor.is_null() {
140 log::error!("Attempting to release an Accessor that was already released");
141 return ptr::null_mut();
142 }
143 let ptr = self.accessor;
144 self.accessor = ptr::null_mut();
145 ptr
146 }
147
148 /// Callback invoked from C++ when the connection info is needed.
149 ///
150 /// # Safety
151 ///
152 /// - The `instance` parameter must be a non-null pointer to a valid C string for
153 /// CStr::from_ptr. The memory must contain a valid null terminator at the end of
154 /// the string within isize::MAX from the pointer. The memory must not be mutated for
155 /// the duration of this function call and must be valid for reads from the pointer
156 /// to the null terminator.
157 /// - The `cookie` parameter must be the cookie for an `Arc<F>` and
158 /// the caller must hold a ref-count to it.
connection_info<F>( instance: *const c_char, cookie: *mut c_void, ) -> *mut binder_ndk_sys::ABinderRpc_ConnectionInfo where F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static,159 unsafe extern "C" fn connection_info<F>(
160 instance: *const c_char,
161 cookie: *mut c_void,
162 ) -> *mut binder_ndk_sys::ABinderRpc_ConnectionInfo
163 where
164 F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static,
165 {
166 if cookie.is_null() || instance.is_null() {
167 log::error!("Cookie({cookie:p}) or instance({instance:p}) is null!");
168 return ptr::null_mut();
169 }
170 // Safety: The caller promises that `cookie` is for an Arc<F>.
171 let callback = unsafe { (cookie as *const F).as_ref().unwrap() };
172
173 // Safety: The caller in libbinder_ndk will have already verified this is a valid
174 // C string
175 let inst = unsafe {
176 match CStr::from_ptr(instance).to_str() {
177 Ok(s) => s,
178 Err(err) => {
179 log::error!("Failed to get a valid C string! {err:?}");
180 return ptr::null_mut();
181 }
182 }
183 };
184
185 let connection = match callback(inst) {
186 Some(con) => con,
187 None => {
188 return ptr::null_mut();
189 }
190 };
191
192 match connection {
193 ConnectionInfo::Vsock(addr) => {
194 // Safety: The sockaddr is being copied in the NDK API
195 unsafe {
196 sys::ABinderRpc_ConnectionInfo_new(
197 &addr as *const sockaddr_vm as *const sockaddr,
198 mem::size_of::<sockaddr_vm>() as socklen_t,
199 )
200 }
201 }
202 ConnectionInfo::Unix(addr) => {
203 // Safety: The sockaddr is being copied in the NDK API
204 // The cast is from sockaddr_un* to sockaddr*.
205 unsafe {
206 sys::ABinderRpc_ConnectionInfo_new(
207 &addr as *const sockaddr_un as *const sockaddr,
208 mem::size_of::<sockaddr_un>() as socklen_t,
209 )
210 }
211 }
212 }
213 }
214
215 /// Callback that decrements the ref-count.
216 /// This is invoked from C++ when a binder is unlinked.
217 ///
218 /// # Safety
219 ///
220 /// - The `cookie` parameter must be the cookie for an `Arc<F>` and
221 /// the owner must give up a ref-count to it.
cookie_decr_refcount<F>(cookie: *mut c_void) where F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static,222 unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void)
223 where
224 F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static,
225 {
226 // Safety: The caller promises that `cookie` is for an Arc<F>.
227 unsafe { Arc::decrement_strong_count(cookie as *const F) };
228 }
229 }
230
231 impl Drop for Accessor {
drop(&mut self)232 fn drop(&mut self) {
233 if self.accessor.is_null() {
234 // This Accessor was already released.
235 return;
236 }
237 // Safety: `self.accessor` is always a valid, owned
238 // `ABinderRpc_Accessor` pointer returned by
239 // `ABinderRpc_Accessor_new` when `self` was created. This delete
240 // method can only be called once when `self` is dropped.
241 unsafe {
242 sys::ABinderRpc_Accessor_delete(self.accessor);
243 }
244 }
245 }
246
247 /// Register a new service with the default service manager.
248 ///
249 /// Registers the given binder object with the given identifier. If successful,
250 /// this service can then be retrieved using that identifier.
251 ///
252 /// This function will panic if the identifier contains a 0 byte (NUL).
delegate_accessor(name: &str, mut binder: SpIBinder) -> Result<SpIBinder>253 pub fn delegate_accessor(name: &str, mut binder: SpIBinder) -> Result<SpIBinder> {
254 let instance = CString::new(name).unwrap();
255 let mut delegator = ptr::null_mut();
256 let status =
257 // Safety: `AServiceManager_addService` expects valid `AIBinder` and C
258 // string pointers. Caller retains ownership of both pointers.
259 // `AServiceManager_addService` creates a new strong reference and copies
260 // the string, so both pointers need only be valid until the call returns.
261 unsafe { sys::ABinderRpc_Accessor_delegateAccessor(instance.as_ptr(),
262 binder.as_native_mut(), &mut delegator) };
263
264 status_result(status)?;
265
266 // Safety: `delegator` is either null or a valid, owned pointer at this
267 // point, so can be safely passed to `SpIBinder::from_raw`.
268 Ok(unsafe { SpIBinder::from_raw(delegator).expect("Expected valid binder at this point") })
269 }
270
271 /// Rust wrapper around ABinderRpc_AccessorProvider objects for RPC binder service management.
272 ///
273 /// Dropping the `AccessorProvider` will drop/unregister the underlying object.
274 #[derive(Debug)]
275 pub struct AccessorProvider {
276 accessor_provider: *mut sys::ABinderRpc_AccessorProvider,
277 }
278
279 /// Safety: A `AccessorProvider` is a wrapper around `ABinderRpc_AccessorProvider` which is
280 /// `Sync` and `Send`. As
281 /// `ABinderRpc_AccessorProvider` is threadsafe, this structure is too.
282 /// The Fn owned the AccessorProvider has `Sync` and `Send` properties
283 unsafe impl Send for AccessorProvider {}
284
285 /// Safety: A `AccessorProvider` is a wrapper around `ABinderRpc_AccessorProvider` which is
286 /// `Sync` and `Send`. As `ABinderRpc_AccessorProvider` is threadsafe, this structure is too.
287 /// The Fn owned the AccessorProvider has `Sync` and `Send` properties
288 unsafe impl Sync for AccessorProvider {}
289
290 impl AccessorProvider {
291 /// Create a new `AccessorProvider` that will give libbinder `Accessors` in order to
292 /// connect to binder services over sockets.
293 ///
294 /// `instances` is a list of all instances that this `AccessorProvider` is responsible for.
295 /// It is declaring these instances as available to this process and will return
296 /// `Accessor` objects for them when libbinder calls the `provider` callback.
297 /// `provider` is the callback that libbinder will call when a service is being requested.
298 /// The callback takes a `&str` argument representing the service that is being requested.
299 /// See the `ABinderRpc_AccessorProvider_getAccessorCallback` for the C++ equivalent.
new<F>(instances: &[String], provider: F) -> Option<AccessorProvider> where F: Fn(&str) -> Option<Accessor> + Send + Sync + 'static,300 pub fn new<F>(instances: &[String], provider: F) -> Option<AccessorProvider>
301 where
302 F: Fn(&str) -> Option<Accessor> + Send + Sync + 'static,
303 {
304 let callback: *mut c_void = Arc::into_raw(Arc::new(provider)) as *mut c_void;
305 let c_str_instances: Vec<CString> =
306 instances.iter().map(|s| CString::new(s.as_bytes()).unwrap()).collect();
307 let mut c_instances: Vec<*const c_char> =
308 c_str_instances.iter().map(|s| s.as_ptr()).collect();
309 let num_instances: usize = c_instances.len();
310 // Safety:
311 // - The function pointer for the first argument is a valid `get_accessor` callback.
312 // - This call returns an owned `ABinderRpc_AccessorProvider` pointer which
313 // must be destroyed via `ABinderRpc_unregisterAccessorProvider` when no longer
314 // needed.
315 // - When the underlying ABinderRpc_AccessorProvider is deleted, it will call
316 // the `cookie_decr_refcount` callback on the `callback` pointer to release its
317 // strong ref.
318 // - The `c_instances` vector is not modified by the function
319 let accessor_provider = unsafe {
320 sys::ABinderRpc_registerAccessorProvider(
321 Some(Self::get_accessor::<F>),
322 c_instances.as_mut_ptr(),
323 num_instances,
324 callback,
325 Some(Self::accessor_cookie_decr_refcount::<F>),
326 )
327 };
328
329 if accessor_provider.is_null() {
330 return None;
331 }
332 Some(AccessorProvider { accessor_provider })
333 }
334
335 /// Callback invoked from C++ when an Accessor is needed.
336 ///
337 /// # Safety
338 ///
339 /// - libbinder guarantees the `instance` argument is a valid C string if it's not null.
340 /// - The `cookie` pointer is same pointer that we pass to ABinderRpc_registerAccessorProvider
341 /// in AccessorProvider.new() which is the closure that we will delete with
342 /// self.accessor_cookie_decr_refcount when unregistering the AccessorProvider.
get_accessor<F>( instance: *const c_char, cookie: *mut c_void, ) -> *mut binder_ndk_sys::ABinderRpc_Accessor where F: Fn(&str) -> Option<Accessor> + Send + Sync + 'static,343 unsafe extern "C" fn get_accessor<F>(
344 instance: *const c_char,
345 cookie: *mut c_void,
346 ) -> *mut binder_ndk_sys::ABinderRpc_Accessor
347 where
348 F: Fn(&str) -> Option<Accessor> + Send + Sync + 'static,
349 {
350 if cookie.is_null() || instance.is_null() {
351 log::error!("Cookie({cookie:p}) or instance({instance:p}) is null!");
352 return ptr::null_mut();
353 }
354 // Safety: The caller promises that `cookie` is for an Arc<F>.
355 let callback = unsafe { (cookie as *const F).as_ref().unwrap() };
356
357 let inst = {
358 // Safety: The caller in libbinder_ndk will have already verified this is a valid
359 // C string
360 match unsafe { CStr::from_ptr(instance) }.to_str() {
361 Ok(s) => s,
362 Err(err) => {
363 log::error!("Failed to get a valid C string! {err:?}");
364 return ptr::null_mut();
365 }
366 }
367 };
368
369 match callback(inst) {
370 Some(a) => {
371 // Safety: This is giving up ownership of this ABinderRpc_Accessor
372 // to the caller of this function (libbinder) and it is responsible
373 // for deleting it.
374 unsafe { a.release() }
375 }
376 None => ptr::null_mut(),
377 }
378 }
379
380 /// Callback that decrements the ref-count.
381 /// This is invoked from C++ when the provider is unregistered.
382 ///
383 /// # Safety
384 ///
385 /// - The `cookie` parameter must be the cookie for an `Arc<F>` and
386 /// the owner must give up a ref-count to it.
accessor_cookie_decr_refcount<F>(cookie: *mut c_void) where F: Fn(&str) -> Option<Accessor> + Send + Sync + 'static,387 unsafe extern "C" fn accessor_cookie_decr_refcount<F>(cookie: *mut c_void)
388 where
389 F: Fn(&str) -> Option<Accessor> + Send + Sync + 'static,
390 {
391 // Safety: The caller promises that `cookie` is for an Arc<F>.
392 unsafe { Arc::decrement_strong_count(cookie as *const F) };
393 }
394 }
395
396 impl Drop for AccessorProvider {
drop(&mut self)397 fn drop(&mut self) {
398 // Safety: `self.accessor_provider` is always a valid, owned
399 // `ABinderRpc_AccessorProvider` pointer returned by
400 // `ABinderRpc_registerAccessorProvider` when `self` was created. This delete
401 // method can only be called once when `self` is dropped.
402 unsafe {
403 sys::ABinderRpc_unregisterAccessorProvider(self.accessor_provider);
404 }
405 }
406 }
407