allocation.rs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2025 Google LLC.
  3. use core::mem::{size_of, size_of_val, MaybeUninit};
  4. use core::ops::Range;
  5. use kernel::{
  6. bindings,
  7. fs::file::{File, FileDescriptorReservation},
  8. prelude::*,
  9. sync::{aref::ARef, Arc},
  10. transmute::{AsBytes, FromBytes},
  11. uaccess::UserSliceReader,
  12. uapi,
  13. };
  14. use crate::{
  15. deferred_close::DeferredFdCloser,
  16. defs::*,
  17. node::{Node, NodeRef},
  18. process::Process,
  19. DArc,
  20. };
  21. #[derive(Default)]
  22. pub(crate) struct AllocationInfo {
  23. /// Range within the allocation where we can find the offsets to the object descriptors.
  24. pub(crate) offsets: Option<Range<usize>>,
  25. /// The target node of the transaction this allocation is associated to.
  26. /// Not set for replies.
  27. pub(crate) target_node: Option<NodeRef>,
  28. /// When this allocation is dropped, call `pending_oneway_finished` on the node.
  29. ///
  30. /// This is used to serialize oneway transaction on the same node. Binder guarantees that
  31. /// oneway transactions to the same node are delivered sequentially in the order they are sent.
  32. pub(crate) oneway_node: Option<DArc<Node>>,
  33. /// Zero the data in the buffer on free.
  34. pub(crate) clear_on_free: bool,
  35. /// List of files embedded in this transaction.
  36. file_list: FileList,
  37. }
  38. /// Represents an allocation that the kernel is currently using.
  39. ///
  40. /// When allocations are idle, the range allocator holds the data related to them.
  41. ///
  42. /// # Invariants
  43. ///
  44. /// This allocation corresponds to an allocation in the range allocator, so the relevant pages are
  45. /// marked in use in the page range.
  46. pub(crate) struct Allocation {
  47. pub(crate) offset: usize,
  48. size: usize,
  49. pub(crate) ptr: usize,
  50. pub(crate) process: Arc<Process>,
  51. allocation_info: Option<AllocationInfo>,
  52. free_on_drop: bool,
  53. pub(crate) oneway_spam_detected: bool,
  54. #[allow(dead_code)]
  55. pub(crate) debug_id: usize,
  56. }
  57. impl Allocation {
  58. pub(crate) fn new(
  59. process: Arc<Process>,
  60. debug_id: usize,
  61. offset: usize,
  62. size: usize,
  63. ptr: usize,
  64. oneway_spam_detected: bool,
  65. ) -> Self {
  66. Self {
  67. process,
  68. offset,
  69. size,
  70. ptr,
  71. debug_id,
  72. oneway_spam_detected,
  73. allocation_info: None,
  74. free_on_drop: true,
  75. }
  76. }
  77. fn size_check(&self, offset: usize, size: usize) -> Result {
  78. let overflow_fail = offset.checked_add(size).is_none();
  79. let cmp_size_fail = offset.wrapping_add(size) > self.size;
  80. if overflow_fail || cmp_size_fail {
  81. return Err(EFAULT);
  82. }
  83. Ok(())
  84. }
  85. pub(crate) fn copy_into(
  86. &self,
  87. reader: &mut UserSliceReader,
  88. offset: usize,
  89. size: usize,
  90. ) -> Result {
  91. self.size_check(offset, size)?;
  92. // SAFETY: While this object exists, the range allocator will keep the range allocated, and
  93. // in turn, the pages will be marked as in use.
  94. unsafe {
  95. self.process
  96. .pages
  97. .copy_from_user_slice(reader, self.offset + offset, size)
  98. }
  99. }
  100. pub(crate) fn read<T: FromBytes>(&self, offset: usize) -> Result<T> {
  101. self.size_check(offset, size_of::<T>())?;
  102. // SAFETY: While this object exists, the range allocator will keep the range allocated, and
  103. // in turn, the pages will be marked as in use.
  104. unsafe { self.process.pages.read(self.offset + offset) }
  105. }
  106. pub(crate) fn write<T: ?Sized>(&self, offset: usize, obj: &T) -> Result {
  107. self.size_check(offset, size_of_val::<T>(obj))?;
  108. // SAFETY: While this object exists, the range allocator will keep the range allocated, and
  109. // in turn, the pages will be marked as in use.
  110. unsafe { self.process.pages.write(self.offset + offset, obj) }
  111. }
  112. pub(crate) fn fill_zero(&self) -> Result {
  113. // SAFETY: While this object exists, the range allocator will keep the range allocated, and
  114. // in turn, the pages will be marked as in use.
  115. unsafe { self.process.pages.fill_zero(self.offset, self.size) }
  116. }
  117. pub(crate) fn keep_alive(mut self) {
  118. self.process
  119. .buffer_make_freeable(self.offset, self.allocation_info.take());
  120. self.free_on_drop = false;
  121. }
  122. pub(crate) fn set_info(&mut self, info: AllocationInfo) {
  123. self.allocation_info = Some(info);
  124. }
  125. pub(crate) fn get_or_init_info(&mut self) -> &mut AllocationInfo {
  126. self.allocation_info.get_or_insert_with(Default::default)
  127. }
  128. pub(crate) fn set_info_offsets(&mut self, offsets: Range<usize>) {
  129. self.get_or_init_info().offsets = Some(offsets);
  130. }
  131. pub(crate) fn set_info_oneway_node(&mut self, oneway_node: DArc<Node>) {
  132. self.get_or_init_info().oneway_node = Some(oneway_node);
  133. }
  134. pub(crate) fn set_info_clear_on_drop(&mut self) {
  135. self.get_or_init_info().clear_on_free = true;
  136. }
  137. pub(crate) fn set_info_target_node(&mut self, target_node: NodeRef) {
  138. self.get_or_init_info().target_node = Some(target_node);
  139. }
  140. /// Reserve enough space to push at least `num_fds` fds.
  141. pub(crate) fn info_add_fd_reserve(&mut self, num_fds: usize) -> Result {
  142. self.get_or_init_info()
  143. .file_list
  144. .files_to_translate
  145. .reserve(num_fds, GFP_KERNEL)?;
  146. Ok(())
  147. }
  148. pub(crate) fn info_add_fd(
  149. &mut self,
  150. file: ARef<File>,
  151. buffer_offset: usize,
  152. close_on_free: bool,
  153. ) -> Result {
  154. self.get_or_init_info().file_list.files_to_translate.push(
  155. FileEntry {
  156. file,
  157. buffer_offset,
  158. close_on_free,
  159. },
  160. GFP_KERNEL,
  161. )?;
  162. Ok(())
  163. }
  164. pub(crate) fn set_info_close_on_free(&mut self, cof: FdsCloseOnFree) {
  165. self.get_or_init_info().file_list.close_on_free = cof.0;
  166. }
  167. pub(crate) fn translate_fds(&mut self) -> Result<TranslatedFds> {
  168. let file_list = match self.allocation_info.as_mut() {
  169. Some(info) => &mut info.file_list,
  170. None => return Ok(TranslatedFds::new()),
  171. };
  172. let files = core::mem::take(&mut file_list.files_to_translate);
  173. let num_close_on_free = files.iter().filter(|entry| entry.close_on_free).count();
  174. let mut close_on_free = KVec::with_capacity(num_close_on_free, GFP_KERNEL)?;
  175. let mut reservations = KVec::with_capacity(files.len(), GFP_KERNEL)?;
  176. for file_info in files {
  177. let res = FileDescriptorReservation::get_unused_fd_flags(bindings::O_CLOEXEC)?;
  178. let fd = res.reserved_fd();
  179. self.write::<u32>(file_info.buffer_offset, &fd)?;
  180. reservations.push(
  181. Reservation {
  182. res,
  183. file: file_info.file,
  184. },
  185. GFP_KERNEL,
  186. )?;
  187. if file_info.close_on_free {
  188. close_on_free.push(fd, GFP_KERNEL)?;
  189. }
  190. }
  191. Ok(TranslatedFds {
  192. reservations,
  193. close_on_free: FdsCloseOnFree(close_on_free),
  194. })
  195. }
  196. /// Should the looper return to userspace when freeing this allocation?
  197. pub(crate) fn looper_need_return_on_free(&self) -> bool {
  198. // Closing fds involves pushing task_work for execution when we return to userspace. Hence,
  199. // we should return to userspace asap if we are closing fds.
  200. match self.allocation_info {
  201. Some(ref info) => !info.file_list.close_on_free.is_empty(),
  202. None => false,
  203. }
  204. }
  205. }
  206. impl Drop for Allocation {
  207. fn drop(&mut self) {
  208. if !self.free_on_drop {
  209. return;
  210. }
  211. if let Some(mut info) = self.allocation_info.take() {
  212. if let Some(oneway_node) = info.oneway_node.as_ref() {
  213. oneway_node.pending_oneway_finished();
  214. }
  215. info.target_node = None;
  216. if let Some(offsets) = info.offsets.clone() {
  217. let view = AllocationView::new(self, offsets.start);
  218. for i in offsets.step_by(size_of::<usize>()) {
  219. if view.cleanup_object(i).is_err() {
  220. pr_warn!("Error cleaning up object at offset {}\n", i)
  221. }
  222. }
  223. }
  224. for &fd in &info.file_list.close_on_free {
  225. let closer = match DeferredFdCloser::new(GFP_KERNEL) {
  226. Ok(closer) => closer,
  227. Err(kernel::alloc::AllocError) => {
  228. // Ignore allocation failures.
  229. break;
  230. }
  231. };
  232. // Here, we ignore errors. The operation can fail if the fd is not valid, or if the
  233. // method is called from a kthread. However, this is always called from a syscall,
  234. // so the latter case cannot happen, and we don't care about the first case.
  235. let _ = closer.close_fd(fd);
  236. }
  237. if info.clear_on_free {
  238. if let Err(e) = self.fill_zero() {
  239. pr_warn!("Failed to clear data on free: {:?}", e);
  240. }
  241. }
  242. }
  243. self.process.buffer_raw_free(self.ptr);
  244. }
  245. }
  246. /// A wrapper around `Allocation` that is being created.
  247. ///
  248. /// If the allocation is destroyed while wrapped in this wrapper, then the allocation will be
  249. /// considered to be part of a failed transaction. Successful transactions avoid that by calling
  250. /// `success`, which skips the destructor.
  251. #[repr(transparent)]
  252. pub(crate) struct NewAllocation(pub(crate) Allocation);
  253. impl NewAllocation {
  254. pub(crate) fn success(self) -> Allocation {
  255. // This skips the destructor.
  256. //
  257. // SAFETY: This type is `#[repr(transparent)]`, so the layout matches.
  258. unsafe { core::mem::transmute(self) }
  259. }
  260. }
  261. impl core::ops::Deref for NewAllocation {
  262. type Target = Allocation;
  263. fn deref(&self) -> &Allocation {
  264. &self.0
  265. }
  266. }
  267. impl core::ops::DerefMut for NewAllocation {
  268. fn deref_mut(&mut self) -> &mut Allocation {
  269. &mut self.0
  270. }
  271. }
  272. /// A view into the beginning of an allocation.
  273. ///
  274. /// All attempts to read or write outside of the view will fail. To intentionally access outside of
  275. /// this view, use the `alloc` field of this struct directly.
  276. pub(crate) struct AllocationView<'a> {
  277. pub(crate) alloc: &'a mut Allocation,
  278. limit: usize,
  279. }
  280. impl<'a> AllocationView<'a> {
  281. pub(crate) fn new(alloc: &'a mut Allocation, limit: usize) -> Self {
  282. AllocationView { alloc, limit }
  283. }
  284. pub(crate) fn read<T: FromBytes>(&self, offset: usize) -> Result<T> {
  285. if offset.checked_add(size_of::<T>()).ok_or(EINVAL)? > self.limit {
  286. return Err(EINVAL);
  287. }
  288. self.alloc.read(offset)
  289. }
  290. pub(crate) fn write<T: AsBytes>(&self, offset: usize, obj: &T) -> Result {
  291. if offset.checked_add(size_of::<T>()).ok_or(EINVAL)? > self.limit {
  292. return Err(EINVAL);
  293. }
  294. self.alloc.write(offset, obj)
  295. }
  296. pub(crate) fn copy_into(
  297. &self,
  298. reader: &mut UserSliceReader,
  299. offset: usize,
  300. size: usize,
  301. ) -> Result {
  302. if offset.checked_add(size).ok_or(EINVAL)? > self.limit {
  303. return Err(EINVAL);
  304. }
  305. self.alloc.copy_into(reader, offset, size)
  306. }
  307. pub(crate) fn transfer_binder_object(
  308. &self,
  309. offset: usize,
  310. obj: &uapi::flat_binder_object,
  311. strong: bool,
  312. node_ref: NodeRef,
  313. ) -> Result {
  314. let mut newobj = FlatBinderObject::default();
  315. let node = node_ref.node.clone();
  316. if Arc::ptr_eq(&node_ref.node.owner, &self.alloc.process) {
  317. // The receiving process is the owner of the node, so send it a binder object (instead
  318. // of a handle).
  319. let (ptr, cookie) = node.get_id();
  320. newobj.hdr.type_ = if strong {
  321. BINDER_TYPE_BINDER
  322. } else {
  323. BINDER_TYPE_WEAK_BINDER
  324. };
  325. newobj.flags = obj.flags;
  326. newobj.__bindgen_anon_1.binder = ptr as _;
  327. newobj.cookie = cookie as _;
  328. self.write(offset, &newobj)?;
  329. // Increment the user ref count on the node. It will be decremented as part of the
  330. // destruction of the buffer, when we see a binder or weak-binder object.
  331. node.update_refcount(true, 1, strong);
  332. } else {
  333. // The receiving process is different from the owner, so we need to insert a handle to
  334. // the binder object.
  335. let handle = self
  336. .alloc
  337. .process
  338. .as_arc_borrow()
  339. .insert_or_update_handle(node_ref, false)?;
  340. newobj.hdr.type_ = if strong {
  341. BINDER_TYPE_HANDLE
  342. } else {
  343. BINDER_TYPE_WEAK_HANDLE
  344. };
  345. newobj.flags = obj.flags;
  346. newobj.__bindgen_anon_1.handle = handle;
  347. if self.write(offset, &newobj).is_err() {
  348. // Decrement ref count on the handle we just created.
  349. let _ = self
  350. .alloc
  351. .process
  352. .as_arc_borrow()
  353. .update_ref(handle, false, strong);
  354. return Err(EINVAL);
  355. }
  356. }
  357. Ok(())
  358. }
  359. fn cleanup_object(&self, index_offset: usize) -> Result {
  360. let offset = self.alloc.read(index_offset)?;
  361. let header = self.read::<BinderObjectHeader>(offset)?;
  362. match header.type_ {
  363. BINDER_TYPE_WEAK_BINDER | BINDER_TYPE_BINDER => {
  364. let obj = self.read::<FlatBinderObject>(offset)?;
  365. let strong = header.type_ == BINDER_TYPE_BINDER;
  366. // SAFETY: The type is `BINDER_TYPE_{WEAK_}BINDER`, so the `binder` field is
  367. // populated.
  368. let ptr = unsafe { obj.__bindgen_anon_1.binder };
  369. let cookie = obj.cookie;
  370. self.alloc.process.update_node(ptr, cookie, strong);
  371. Ok(())
  372. }
  373. BINDER_TYPE_WEAK_HANDLE | BINDER_TYPE_HANDLE => {
  374. let obj = self.read::<FlatBinderObject>(offset)?;
  375. let strong = header.type_ == BINDER_TYPE_HANDLE;
  376. // SAFETY: The type is `BINDER_TYPE_{WEAK_}HANDLE`, so the `handle` field is
  377. // populated.
  378. let handle = unsafe { obj.__bindgen_anon_1.handle };
  379. self.alloc
  380. .process
  381. .as_arc_borrow()
  382. .update_ref(handle, false, strong)
  383. }
  384. _ => Ok(()),
  385. }
  386. }
  387. }
  388. /// A binder object as it is serialized.
  389. ///
  390. /// # Invariants
  391. ///
  392. /// All bytes must be initialized, and the value of `self.hdr.type_` must be one of the allowed
  393. /// types.
  394. #[repr(C)]
  395. pub(crate) union BinderObject {
  396. hdr: uapi::binder_object_header,
  397. fbo: uapi::flat_binder_object,
  398. fdo: uapi::binder_fd_object,
  399. bbo: uapi::binder_buffer_object,
  400. fdao: uapi::binder_fd_array_object,
  401. }
  402. /// A view into a `BinderObject` that can be used in a match statement.
  403. pub(crate) enum BinderObjectRef<'a> {
  404. Binder(&'a mut uapi::flat_binder_object),
  405. Handle(&'a mut uapi::flat_binder_object),
  406. Fd(&'a mut uapi::binder_fd_object),
  407. Ptr(&'a mut uapi::binder_buffer_object),
  408. Fda(&'a mut uapi::binder_fd_array_object),
  409. }
  410. impl BinderObject {
  411. pub(crate) fn read_from(reader: &mut UserSliceReader) -> Result<BinderObject> {
  412. let object = Self::read_from_inner(|slice| {
  413. let read_len = usize::min(slice.len(), reader.len());
  414. reader.clone_reader().read_slice(&mut slice[..read_len])?;
  415. Ok(())
  416. })?;
  417. // If we used a object type smaller than the largest object size, then we've read more
  418. // bytes than we needed to. However, we used `.clone_reader()` to avoid advancing the
  419. // original reader. Now, we call `skip` so that the caller's reader is advanced by the
  420. // right amount.
  421. //
  422. // The `skip` call fails if the reader doesn't have `size` bytes available. This could
  423. // happen if the type header corresponds to an object type that is larger than the rest of
  424. // the reader.
  425. //
  426. // Any extra bytes beyond the size of the object are inaccessible after this call, so
  427. // reading them again from the `reader` later does not result in TOCTOU bugs.
  428. reader.skip(object.size())?;
  429. Ok(object)
  430. }
  431. /// Use the provided reader closure to construct a `BinderObject`.
  432. ///
  433. /// The closure should write the bytes for the object into the provided slice.
  434. pub(crate) fn read_from_inner<R>(reader: R) -> Result<BinderObject>
  435. where
  436. R: FnOnce(&mut [u8; size_of::<BinderObject>()]) -> Result<()>,
  437. {
  438. let mut obj = MaybeUninit::<BinderObject>::zeroed();
  439. // SAFETY: The lengths of `BinderObject` and `[u8; size_of::<BinderObject>()]` are equal,
  440. // and the byte array has an alignment requirement of one, so the pointer cast is okay.
  441. // Additionally, `obj` was initialized to zeros, so the byte array will not be
  442. // uninitialized.
  443. (reader)(unsafe { &mut *obj.as_mut_ptr().cast() })?;
  444. // SAFETY: The entire object is initialized, so accessing this field is safe.
  445. let type_ = unsafe { obj.assume_init_ref().hdr.type_ };
  446. if Self::type_to_size(type_).is_none() {
  447. // The value of `obj.hdr_type_` was invalid.
  448. return Err(EINVAL);
  449. }
  450. // SAFETY: All bytes are initialized (since we zeroed them at the start) and we checked
  451. // that `self.hdr.type_` is one of the allowed types, so the type invariants are satisfied.
  452. unsafe { Ok(obj.assume_init()) }
  453. }
  454. pub(crate) fn as_ref(&mut self) -> BinderObjectRef<'_> {
  455. use BinderObjectRef::*;
  456. // SAFETY: The constructor ensures that all bytes of `self` are initialized, and all
  457. // variants of this union accept all initialized bit patterns.
  458. unsafe {
  459. match self.hdr.type_ {
  460. BINDER_TYPE_WEAK_BINDER | BINDER_TYPE_BINDER => Binder(&mut self.fbo),
  461. BINDER_TYPE_WEAK_HANDLE | BINDER_TYPE_HANDLE => Handle(&mut self.fbo),
  462. BINDER_TYPE_FD => Fd(&mut self.fdo),
  463. BINDER_TYPE_PTR => Ptr(&mut self.bbo),
  464. BINDER_TYPE_FDA => Fda(&mut self.fdao),
  465. // SAFETY: By the type invariant, the value of `self.hdr.type_` cannot have any
  466. // other value than the ones checked above.
  467. _ => core::hint::unreachable_unchecked(),
  468. }
  469. }
  470. }
  471. pub(crate) fn size(&self) -> usize {
  472. // SAFETY: The entire object is initialized, so accessing this field is safe.
  473. let type_ = unsafe { self.hdr.type_ };
  474. // SAFETY: The type invariants guarantee that the type field is correct.
  475. unsafe { Self::type_to_size(type_).unwrap_unchecked() }
  476. }
  477. fn type_to_size(type_: u32) -> Option<usize> {
  478. match type_ {
  479. BINDER_TYPE_WEAK_BINDER => Some(size_of::<uapi::flat_binder_object>()),
  480. BINDER_TYPE_BINDER => Some(size_of::<uapi::flat_binder_object>()),
  481. BINDER_TYPE_WEAK_HANDLE => Some(size_of::<uapi::flat_binder_object>()),
  482. BINDER_TYPE_HANDLE => Some(size_of::<uapi::flat_binder_object>()),
  483. BINDER_TYPE_FD => Some(size_of::<uapi::binder_fd_object>()),
  484. BINDER_TYPE_PTR => Some(size_of::<uapi::binder_buffer_object>()),
  485. BINDER_TYPE_FDA => Some(size_of::<uapi::binder_fd_array_object>()),
  486. _ => None,
  487. }
  488. }
  489. }
  490. #[derive(Default)]
  491. struct FileList {
  492. files_to_translate: KVec<FileEntry>,
  493. close_on_free: KVec<u32>,
  494. }
  495. struct FileEntry {
  496. /// The file for which a descriptor will be created in the recipient process.
  497. file: ARef<File>,
  498. /// The offset in the buffer where the file descriptor is stored.
  499. buffer_offset: usize,
  500. /// Whether this fd should be closed when the allocation is freed.
  501. close_on_free: bool,
  502. }
  503. pub(crate) struct TranslatedFds {
  504. reservations: KVec<Reservation>,
  505. /// If commit is called, then these fds should be closed. (If commit is not called, then they
  506. /// shouldn't be closed.)
  507. close_on_free: FdsCloseOnFree,
  508. }
  509. struct Reservation {
  510. res: FileDescriptorReservation,
  511. file: ARef<File>,
  512. }
  513. impl TranslatedFds {
  514. pub(crate) fn new() -> Self {
  515. Self {
  516. reservations: KVec::new(),
  517. close_on_free: FdsCloseOnFree(KVec::new()),
  518. }
  519. }
  520. pub(crate) fn commit(self) -> FdsCloseOnFree {
  521. for entry in self.reservations {
  522. entry.res.fd_install(entry.file);
  523. }
  524. self.close_on_free
  525. }
  526. }
  527. pub(crate) struct FdsCloseOnFree(KVec<u32>);