binder_rust/
parcel.rs

1use std::{
2    ffi::c_void,
3    fmt,
4    io::{Cursor, Read, Write},
5    mem::size_of,
6    mem::transmute,
7    os::unix::io::RawFd,
8    slice,
9};
10
11use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
12
13use crate::{Binder, BinderFlatObject, BinderTransactionData, BinderType};
14
15const STRICT_MODE_PENALTY_GATHER: i32 = 1 << 31;
16/// The header marker, packed["S", "Y", "S", "T"];
17const HEADER: i32 = 0x53595354;
18
19/// Represents a binder serializable parcel
20pub struct Parcel {
21    cursor: Cursor<Vec<u8>>,
22    object_offsets: Vec<usize>,
23    objects_position: usize,
24}
25
26impl fmt::Debug for Parcel {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        f.debug_struct("Parcel")
29            .field("data", &self.cursor.get_ref())
30            .field("offsets", &self.object_offsets)
31            .finish()
32    }
33}
34impl Parcel {
35    /// Create a new empty parcel.
36    pub fn empty() -> Self {
37        let data = vec![];
38        Self {
39            cursor: Cursor::new(data),
40            object_offsets: vec![],
41            objects_position: 0,
42        }
43    }
44
45    /// Create a new empty parcel, with a reserved size
46    pub fn from_slice(data: &[u8]) -> Self {
47        Self {
48            cursor: Cursor::new(data.to_vec()),
49            object_offsets: vec![],
50            objects_position: 0,
51        }
52    }
53
54    pub fn from_data_and_offsets(
55        data: *mut u8,
56        data_size: usize,
57        offsets: *mut usize,
58        offsets_size: usize,
59    ) -> Self {
60        unsafe {
61            Self {
62                cursor: Cursor::new(slice::from_raw_parts(data, data_size).to_vec()),
63                object_offsets: slice::from_raw_parts(offsets, offsets_size).to_vec(),
64                objects_position: 0,
65            }
66        }
67    }
68
69    pub fn reset(&mut self) {
70        self.cursor.set_position(0);
71        self.cursor.get_mut().resize(0, 0);
72        self.objects_position = 0;
73        self.object_offsets.resize(0, 0);
74    }
75
76    pub fn position(&self) -> u64 {
77        self.cursor.position()
78    }
79
80    pub fn set_position(&mut self, pos: u64) {
81        self.cursor.set_position(pos)
82    }
83
84    /// Append the contents of another parcel to this parcel
85    pub fn append_parcel(&mut self, other: &mut Parcel) {
86        let current_position = self.cursor.position();
87        self.cursor.write(other.to_slice());
88        for offset in &other.object_offsets {
89            self.object_offsets.push(offset + current_position as usize);
90        }
91    }
92
93    /// Retrieve the data of the parcel as a pointer
94    pub fn as_ptr(&self) -> *const u8 {
95        self.cursor.get_ref().as_ptr()
96    }
97
98    /// Retrieve the data of the parcel as a mutable pointer
99    pub fn as_mut_ptr(&mut self) -> *mut u8 {
100        self.cursor.get_mut().as_mut_ptr()
101    }
102
103    /// Retrieve the data of the parce as a slice
104    pub fn to_slice(&self) -> &[u8] {
105        self.cursor.get_ref()
106    }
107    /// Retrieve the size of the parcel's data
108    pub fn len(&self) -> usize {
109        self.cursor.get_ref().len()
110    }
111
112    /// Retrieve the number of object offsets
113    pub fn offsets_len(&self) -> usize {
114        self.object_offsets.len()
115    }
116
117    /// Retrieve the object offsets
118    pub fn offsets(&mut self) -> &mut Vec<usize> {
119        &mut self.object_offsets
120    }
121
122    /// Check if the parcel has unread data
123    pub fn has_unread_data(&self) -> bool {
124        self.cursor.position() != self.len() as u64
125    }
126
127    /// Write an i32 to the parcel
128    pub fn write_i32(&mut self, data: i32) {
129        self.cursor.write_i32::<LittleEndian>(data);
130    }
131    /// Write an u32 to the parcel
132    pub fn write_u32(&mut self, data: u32) {
133        self.cursor.write_u32::<LittleEndian>(data);
134    }
135    /// Write an u16 to the parcel
136    pub fn write_u16(&mut self, data: u16) {
137        self.cursor.write_u16::<LittleEndian>(data);
138    }
139
140    /// Write a bool to the parcel
141    pub fn write_bool(&mut self, data: bool) {
142        self.cursor.write_u32::<LittleEndian>(data as u32);
143    }
144
145    /// Read an i32 from the parcel
146    pub fn read_i32(&mut self) -> i32 {
147        self.cursor.read_i32::<LittleEndian>().unwrap()
148    }
149
150    /// Write a slice of data to the parcel
151    pub fn write(&mut self, data: &[u8]) {
152        let padded_len = (data.len() + 3) & !3;
153
154        let mut data = data.to_vec();
155        if padded_len > data.len() {
156            data.resize(padded_len, 0);
157        };
158
159        self.cursor
160            .write(data.as_slice())
161            .expect("Coudn't write to parcel data");
162    }
163
164    /// Write a BinderTransactionData struct into the parcel
165    pub fn write_transaction_data(&mut self, data: &BinderTransactionData) {
166        self.write(unsafe {
167            slice::from_raw_parts(
168                data as *const _ as *const u8,
169                size_of::<BinderTransactionData>(),
170            )
171        });
172    }
173
174    /// Read an u32 from the parcel
175    pub fn read_u32(&mut self) -> u32 {
176        self.cursor.read_u32::<LittleEndian>().unwrap()
177    }
178
179    /// Read an u64 from the parcel
180    pub fn read_u64(&mut self) -> u64 {
181        self.cursor.read_u64::<LittleEndian>().unwrap()
182    }
183
184    /// Read an usize from the parcel
185    pub fn read_usize(&mut self) -> usize {
186        if size_of::<usize>() == size_of::<u32>() {
187            self.read_u32() as usize
188        } else {
189            self.read_u64() as usize
190        }
191    }
192
193    /// Read a void pointer from the parcel
194    pub fn read_pointer(&mut self) -> *const c_void {
195        self.read_usize() as *const c_void
196    }
197
198    /// Read a slice of size bytes from the parcel
199    pub fn read(&mut self, size: usize) -> Vec<u8> {
200        let size = if (size % 4) != 0 {
201            size + 4 - (size % 4)
202        } else {
203            size
204        };
205        let mut data = vec![0u8; size];
206        self.cursor.read(&mut data);
207        data
208    }
209    /// Read a slice of size bytes from the parcel
210    pub fn read_without_alignment(&mut self, size: usize) -> Vec<u8> {
211        let mut data = vec![0u8; size];
212        self.cursor.read(&mut data);
213        data
214    }
215
216    /// Read a BinderTransactionData from the parcel
217    pub fn read_transaction_data(&mut self) -> BinderTransactionData {
218        self.read_object()
219    }
220
221    /// Read an object of type T from the parcel
222    pub fn read_object<T>(&mut self) -> T {
223        unsafe {
224            let data = slice::from_raw_parts(
225                self.cursor
226                    .get_ref()
227                    .as_ptr()
228                    .offset(self.cursor.position() as isize),
229                size_of::<T>(),
230            );
231            self.cursor.set_position(self.cursor.position() + size_of::<T>() as u64);
232            (data.as_ptr() as *const T).read()
233        }
234    }
235
236    pub fn write_object<T>(&mut self, object: T) {
237        self.object_offsets.push(self.cursor.position() as usize);
238        self.cursor.write(unsafe {
239            slice::from_raw_parts(&object as *const _ as *const u8, size_of::<T>())
240        });
241
242    }
243
244    /// Write a string to the parcel
245    pub fn write_str16(&mut self, string: &str) {
246        let mut s16: Vec<u8> = vec![];
247        self.write_i32(string.len() as i32);
248        for c in string.encode_utf16() {
249            s16.write_u16::<LittleEndian>(c);
250        }
251        s16.write_u16::<LittleEndian>(0);
252
253        if s16.len() % 4 != 0 {
254            s16.resize(s16.len() + 4 - (s16.len() % 4), 0)
255        }
256
257        self.cursor.write(s16.as_slice());
258    }
259
260    /// Write a Binder object into the parcel
261    pub fn write_binder(&mut self, object: *const c_void) {
262        self.write_object(BinderFlatObject::new(BinderType::Binder, object as usize, 0, 0));
263        self.write_u32(0xc); // stability  == SYSTEM
264    }
265
266    /// Write a file descriptor into the parcel
267    pub fn write_file_descriptor(&mut self, fd: RawFd, take_ownership: bool) {
268        self.write_object(BinderFlatObject::new(BinderType::Fd, fd as usize, if take_ownership { 1 } else { 0 }, 0x17f));
269        //self.write_u32(0xc); // stability  == SYSTEM
270    }
271
272    /// REad a file descriptor from the parcel
273    pub fn read_file_descriptor(&mut self) -> RawFd {
274        let flat_object: BinderFlatObject = self.read_object();
275        assert!(flat_object.binder_type == BinderType::Fd);
276        flat_object.handle as RawFd
277    }
278
279    /// Read a string from the parcel
280    pub fn read_str16(&mut self) -> String {
281        let len = ((self.read_i32() + 1) * 2) as usize;
282        if len == 0 {
283            return "".to_string()
284        }
285        unsafe {
286            let u16_array = slice::from_raw_parts(self.read(len).as_mut_ptr() as *mut u16, len);
287            let mut res = String::from_utf16(u16_array).unwrap();
288            res.truncate(len / 2 - 1);
289            res
290        }
291    }
292
293    /// Read a string from the parcel
294    pub fn read_str(&mut self) -> String {
295        let len = (self.read_i32() + 1) as usize;
296        if len == 0 {
297            return "".to_string()
298        }
299        unsafe {
300            let u8_array = slice::from_raw_parts(self.read(len).as_mut_ptr() as *mut u8, len);
301            let mut res = String::from_utf8(u8_array.to_vec()).unwrap();
302            res.truncate(len - 1);
303            res
304        }
305    }
306
307    /// Read an interface token from the parcel
308    pub fn read_interface_token(&mut self) -> String {
309        assert!(self.read_i32() == STRICT_MODE_PENALTY_GATHER);
310        assert!(self.read_i32() == -1);
311        assert!(self.read_i32() == HEADER);
312        self.read_str16()
313    }
314
315
316    /// Write an interface token to the parcel
317    pub fn write_interface_token(&mut self, name: &str) {
318        // strict mode policy
319        self.write_i32(STRICT_MODE_PENALTY_GATHER);
320        // work source uid, we use kUnsetWorkSource
321        self.write_i32(-1);
322        // header marker
323        self.write_i32(HEADER);
324        // the interface name
325        self.write_str16(name);
326    }
327}