1 /*
2  * Copyright (C) 2020 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 //! Included as a module in the binder crate internal tests for internal API
18 //! access.
19 
20 use binder::declare_binder_interface;
21 use binder::{
22     BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, SpIBinder, Status, StatusCode,
23 };
24 // Import from impl API for testing only, should not be necessary as long as you
25 // are using AIDL.
26 use binder::binder_impl::{Binder, BorrowedParcel, TransactionCode};
27 
28 use std::ffi::{c_void, CStr, CString};
29 use std::sync::OnceLock;
30 
31 #[allow(
32     non_camel_case_types,
33     non_snake_case,
34     non_upper_case_globals,
35     unused,
36     improper_ctypes,
37     missing_docs,
38     clippy::all
39 )]
40 mod bindings {
41     include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
42 }
43 
44 macro_rules! assert_eq {
45     ($left:expr, $right:expr $(,)?) => {
46         match (&$left, &$right) {
47             (left, right) => {
48                 if *left != *right {
49                     eprintln!(
50                         "assertion failed: `{:?}` == `{:?}`, {}:{}:{}",
51                         &*left,
52                         &*right,
53                         file!(),
54                         line!(),
55                         column!()
56                     );
57                     return Err(StatusCode::FAILED_TRANSACTION);
58                 }
59             }
60         }
61     };
62 }
63 
64 macro_rules! assert {
65     ($expr:expr) => {
66         if !$expr {
67             eprintln!("assertion failed: `{:?}`, {}:{}:{}", $expr, file!(), line!(), column!());
68             return Err(StatusCode::FAILED_TRANSACTION);
69         }
70     };
71 }
72 
73 static SERVICE: OnceLock<SpIBinder> = OnceLock::new();
74 
75 /// Start binder service and return a raw AIBinder pointer to it.
76 ///
77 /// Safe to call multiple times, only creates the service once.
78 #[no_mangle]
rust_service() -> *mut c_void79 pub extern "C" fn rust_service() -> *mut c_void {
80     let service = SERVICE
81         .get_or_init(|| BnReadParcelTest::new_binder((), BinderFeatures::default()).as_binder());
82     // SAFETY: The SpIBinder will remain alive as long as the program is running because it is in
83     // the static SERVICE, so the pointer is valid forever.
84     unsafe { service.as_raw().cast() }
85 }
86 
87 /// Empty interface just to use the declare_binder_interface macro
88 pub trait ReadParcelTest: Interface {}
89 
90 declare_binder_interface! {
91     ReadParcelTest["read_parcel_test"] {
92         native: BnReadParcelTest(on_transact),
93         proxy: BpReadParcelTest,
94     }
95 }
96 
97 impl ReadParcelTest for Binder<BnReadParcelTest> {}
98 
99 impl ReadParcelTest for BpReadParcelTest {}
100 
101 impl ReadParcelTest for () {}
102 
103 #[allow(clippy::float_cmp)]
on_transact( _service: &dyn ReadParcelTest, code: TransactionCode, parcel: &BorrowedParcel<'_>, reply: &mut BorrowedParcel<'_>, ) -> Result<(), StatusCode>104 fn on_transact(
105     _service: &dyn ReadParcelTest,
106     code: TransactionCode,
107     parcel: &BorrowedParcel<'_>,
108     reply: &mut BorrowedParcel<'_>,
109 ) -> Result<(), StatusCode> {
110     match code {
111         bindings::Transaction_TEST_BOOL => {
112             assert!(parcel.read::<bool>()?);
113             assert!(!parcel.read::<bool>()?);
114             // SAFETY: Just reading an extern constant.
115             assert_eq!(parcel.read::<Vec<bool>>()?, unsafe { bindings::TESTDATA_BOOL });
116             assert_eq!(parcel.read::<Option<Vec<bool>>>()?, None);
117 
118             reply.write(&true)?;
119             reply.write(&false)?;
120             // SAFETY: Just reading an extern constant.
121             reply.write(&unsafe { bindings::TESTDATA_BOOL }[..])?;
122             reply.write(&(None as Option<Vec<bool>>))?;
123         }
124         bindings::Transaction_TEST_BYTE => {
125             assert_eq!(parcel.read::<i8>()?, 0);
126             assert_eq!(parcel.read::<i8>()?, 1);
127             assert_eq!(parcel.read::<i8>()?, i8::max_value());
128             // SAFETY: Just reading an extern constant.
129             assert_eq!(parcel.read::<Vec<i8>>()?, unsafe { bindings::TESTDATA_I8 });
130             // SAFETY: Just reading an extern constant.
131             assert_eq!(parcel.read::<Vec<u8>>()?, unsafe { bindings::TESTDATA_U8 });
132             assert_eq!(parcel.read::<Option<Vec<i8>>>()?, None);
133 
134             reply.write(&0i8)?;
135             reply.write(&1i8)?;
136             reply.write(&i8::max_value())?;
137             // SAFETY: Just reading an extern constant.
138             reply.write(&unsafe { bindings::TESTDATA_I8 }[..])?;
139             // SAFETY: Just reading an extern constant.
140             reply.write(&unsafe { bindings::TESTDATA_U8 }[..])?;
141             reply.write(&(None as Option<Vec<i8>>))?;
142         }
143         bindings::Transaction_TEST_U16 => {
144             assert_eq!(parcel.read::<u16>()?, 0);
145             assert_eq!(parcel.read::<u16>()?, 1);
146             assert_eq!(parcel.read::<u16>()?, u16::max_value());
147             // SAFETY: Just reading an extern constant.
148             assert_eq!(parcel.read::<Vec<u16>>()?, unsafe { bindings::TESTDATA_CHARS });
149             assert_eq!(parcel.read::<Option<Vec<u16>>>()?, None);
150 
151             reply.write(&0u16)?;
152             reply.write(&1u16)?;
153             reply.write(&u16::max_value())?;
154             // SAFETY: Just reading an extern constant.
155             reply.write(&unsafe { bindings::TESTDATA_CHARS }[..])?;
156             reply.write(&(None as Option<Vec<u16>>))?;
157         }
158         bindings::Transaction_TEST_I32 => {
159             assert_eq!(parcel.read::<i32>()?, 0);
160             assert_eq!(parcel.read::<i32>()?, 1);
161             assert_eq!(parcel.read::<i32>()?, i32::max_value());
162             // SAFETY: Just reading an extern constant.
163             assert_eq!(parcel.read::<Vec<i32>>()?, unsafe { bindings::TESTDATA_I32 });
164             assert_eq!(parcel.read::<Option<Vec<i32>>>()?, None);
165 
166             reply.write(&0i32)?;
167             reply.write(&1i32)?;
168             reply.write(&i32::max_value())?;
169             // SAFETY: Just reading an extern constant.
170             reply.write(&unsafe { bindings::TESTDATA_I32 }[..])?;
171             reply.write(&(None as Option<Vec<i32>>))?;
172         }
173         bindings::Transaction_TEST_I64 => {
174             assert_eq!(parcel.read::<i64>()?, 0);
175             assert_eq!(parcel.read::<i64>()?, 1);
176             assert_eq!(parcel.read::<i64>()?, i64::max_value());
177             // SAFETY: Just reading an extern constant.
178             assert_eq!(parcel.read::<Vec<i64>>()?, unsafe { bindings::TESTDATA_I64 });
179             assert_eq!(parcel.read::<Option<Vec<i64>>>()?, None);
180 
181             reply.write(&0i64)?;
182             reply.write(&1i64)?;
183             reply.write(&i64::max_value())?;
184             // SAFETY: Just reading an extern constant.
185             reply.write(&unsafe { bindings::TESTDATA_I64 }[..])?;
186             reply.write(&(None as Option<Vec<i64>>))?;
187         }
188         bindings::Transaction_TEST_U64 => {
189             assert_eq!(parcel.read::<u64>()?, 0);
190             assert_eq!(parcel.read::<u64>()?, 1);
191             assert_eq!(parcel.read::<u64>()?, u64::max_value());
192             // SAFETY: Just reading an extern constant.
193             assert_eq!(parcel.read::<Vec<u64>>()?, unsafe { bindings::TESTDATA_U64 });
194             assert_eq!(parcel.read::<Option<Vec<u64>>>()?, None);
195 
196             reply.write(&0u64)?;
197             reply.write(&1u64)?;
198             reply.write(&u64::max_value())?;
199             // SAFETY: Just reading an extern constant.
200             reply.write(&unsafe { bindings::TESTDATA_U64 }[..])?;
201             reply.write(&(None as Option<Vec<u64>>))?;
202         }
203         bindings::Transaction_TEST_F32 => {
204             assert_eq!(parcel.read::<f32>()?, 0f32);
205             let floats = parcel.read::<Vec<f32>>()?;
206             assert!(floats[0].is_nan());
207             // SAFETY: Just reading an extern constant.
208             assert_eq!(floats[1..], unsafe { bindings::TESTDATA_FLOAT }[1..]);
209             assert_eq!(parcel.read::<Option<Vec<f32>>>()?, None);
210 
211             reply.write(&0f32)?;
212             // SAFETY: Just reading an extern constant.
213             reply.write(&unsafe { bindings::TESTDATA_FLOAT }[..])?;
214             reply.write(&(None as Option<Vec<f32>>))?;
215         }
216         bindings::Transaction_TEST_F64 => {
217             assert_eq!(parcel.read::<f64>()?, 0f64);
218             let doubles = parcel.read::<Vec<f64>>()?;
219             assert!(doubles[0].is_nan());
220             // SAFETY: Just reading an extern constant.
221             assert_eq!(doubles[1..], unsafe { bindings::TESTDATA_DOUBLE }[1..]);
222             assert_eq!(parcel.read::<Option<Vec<f64>>>()?, None);
223 
224             reply.write(&0f64)?;
225             // SAFETY: Just reading an extern constant.
226             reply.write(&unsafe { bindings::TESTDATA_DOUBLE }[..])?;
227             reply.write(&(None as Option<Vec<f64>>))?;
228         }
229         bindings::Transaction_TEST_STRING => {
230             let s: Option<String> = parcel.read()?;
231             assert_eq!(s.as_deref(), Some("testing"));
232             let s: Option<String> = parcel.read()?;
233             assert_eq!(s, None);
234             let s: Option<Vec<Option<String>>> = parcel.read()?;
235             // SAFETY: Just reading an extern constant.
236             for (s, expected) in s.unwrap().iter().zip(unsafe { bindings::TESTDATA_STRS }.iter()) {
237                 let expected =
238             // SAFETY: Just reading an extern constant.
239                     unsafe { expected.as_ref().and_then(|e| CStr::from_ptr(e).to_str().ok()) };
240                 assert_eq!(s.as_deref(), expected);
241             }
242             let s: Option<Vec<Option<String>>> = parcel.read()?;
243             assert_eq!(s, None);
244 
245             // SAFETY: Just reading an extern constant.
246             let strings: Vec<Option<String>> = unsafe {
247                 bindings::TESTDATA_STRS
248                     .iter()
249                     .map(|s| {
250                         s.as_ref().map(|s| {
251                             CStr::from_ptr(s).to_str().expect("String was not UTF-8").to_owned()
252                         })
253                     })
254                     .collect()
255             };
256 
257             reply.write("testing")?;
258             reply.write(&(None as Option<String>))?;
259             reply.write(&strings)?;
260             reply.write(&(None as Option<Vec<String>>))?;
261         }
262         bindings::Transaction_TEST_FILE_DESCRIPTOR => {
263             let file1 = parcel.read::<ParcelFileDescriptor>()?;
264             let file2 = parcel.read::<ParcelFileDescriptor>()?;
265             let files = parcel.read::<Vec<Option<ParcelFileDescriptor>>>()?;
266 
267             reply.write(&file1)?;
268             reply.write(&file2)?;
269             reply.write(&files)?;
270         }
271         bindings::Transaction_TEST_IBINDER => {
272             assert!(parcel.read::<Option<SpIBinder>>()?.is_some());
273             assert!(parcel.read::<Option<SpIBinder>>()?.is_none());
274             let ibinders = parcel.read::<Option<Vec<Option<SpIBinder>>>>()?.unwrap();
275             assert_eq!(ibinders.len(), 2);
276             assert!(ibinders[0].is_some());
277             assert!(ibinders[1].is_none());
278             assert!(parcel.read::<Option<Vec<Option<SpIBinder>>>>()?.is_none());
279 
280             let service = SERVICE.get().expect("Global binder service not initialized").clone();
281             reply.write(&service)?;
282             reply.write(&(None as Option<&SpIBinder>))?;
283             reply.write(&[Some(&service), None][..])?;
284             reply.write(&(None as Option<Vec<Option<&SpIBinder>>>))?;
285         }
286         bindings::Transaction_TEST_STATUS => {
287             let status: Status = parcel.read()?;
288             assert!(status.is_ok());
289             let status: Status = parcel.read()?;
290             assert_eq!(status.exception_code(), ExceptionCode::NULL_POINTER);
291             assert_eq!(status.get_description(), "Status(-4, EX_NULL_POINTER): 'a status message'");
292             let status: Status = parcel.read()?;
293             assert_eq!(status.service_specific_error(), 42);
294             assert_eq!(
295                 status.get_description(),
296                 "Status(-8, EX_SERVICE_SPECIFIC): '42: a service-specific error'"
297             );
298 
299             reply.write(&Status::ok())?;
300             reply.write(&Status::new_exception(
301                 ExceptionCode::NULL_POINTER,
302                 Some(&CString::new("a status message").unwrap()),
303             ))?;
304             reply.write(&Status::new_service_specific_error(
305                 42,
306                 Some(&CString::new("a service-specific error").unwrap()),
307             ))?;
308         }
309         bindings::Transaction_TEST_FAIL => {
310             assert!(false);
311         }
312         _ => return Err(StatusCode::UNKNOWN_TRANSACTION),
313     }
314 
315     assert_eq!(parcel.read::<i32>(), Err(StatusCode::NOT_ENOUGH_DATA));
316     Ok(())
317 }
318