1 // SPDX-License-Identifier: GPL-2.0 2 3 // Copyright (C) 2024 Google LLC. 4 5 use core::mem::MaybeUninit; 6 use core::ops::{Deref, DerefMut}; 7 use kernel::{ 8 types::{AsBytes, FromBytes}, 9 uapi::{self, *}, 10 }; 11 12 macro_rules! pub_no_prefix { 13 ($prefix:ident, $($newname:ident),+ $(,)?) => { 14 $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+ 15 }; 16 } 17 18 pub_no_prefix!( 19 binder_driver_return_protocol_, 20 BR_TRANSACTION, 21 BR_TRANSACTION_SEC_CTX, 22 BR_REPLY, 23 BR_DEAD_REPLY, 24 BR_FAILED_REPLY, 25 BR_FROZEN_REPLY, 26 BR_NOOP, 27 BR_SPAWN_LOOPER, 28 BR_TRANSACTION_COMPLETE, 29 BR_TRANSACTION_PENDING_FROZEN, 30 BR_ONEWAY_SPAM_SUSPECT, 31 BR_OK, 32 BR_ERROR, 33 BR_INCREFS, 34 BR_ACQUIRE, 35 BR_RELEASE, 36 BR_DECREFS, 37 BR_DEAD_BINDER, 38 BR_CLEAR_DEATH_NOTIFICATION_DONE, 39 BR_FROZEN_BINDER, 40 BR_CLEAR_FREEZE_NOTIFICATION_DONE, 41 ); 42 43 pub_no_prefix!( 44 binder_driver_command_protocol_, 45 BC_TRANSACTION, 46 BC_TRANSACTION_SG, 47 BC_REPLY, 48 BC_REPLY_SG, 49 BC_FREE_BUFFER, 50 BC_ENTER_LOOPER, 51 BC_EXIT_LOOPER, 52 BC_REGISTER_LOOPER, 53 BC_INCREFS, 54 BC_ACQUIRE, 55 BC_RELEASE, 56 BC_DECREFS, 57 BC_INCREFS_DONE, 58 BC_ACQUIRE_DONE, 59 BC_REQUEST_DEATH_NOTIFICATION, 60 BC_CLEAR_DEATH_NOTIFICATION, 61 BC_DEAD_BINDER_DONE, 62 BC_REQUEST_FREEZE_NOTIFICATION, 63 BC_CLEAR_FREEZE_NOTIFICATION, 64 BC_FREEZE_NOTIFICATION_DONE, 65 ); 66 67 pub_no_prefix!( 68 flat_binder_object_shifts_, 69 FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT 70 ); 71 72 pub_no_prefix!( 73 flat_binder_object_flags_, 74 FLAT_BINDER_FLAG_ACCEPTS_FDS, 75 FLAT_BINDER_FLAG_INHERIT_RT, 76 FLAT_BINDER_FLAG_PRIORITY_MASK, 77 FLAT_BINDER_FLAG_SCHED_POLICY_MASK, 78 FLAT_BINDER_FLAG_TXN_SECURITY_CTX 79 ); 80 81 pub_no_prefix!( 82 transaction_flags_, 83 TF_ONE_WAY, 84 TF_ACCEPT_FDS, 85 TF_CLEAR_BUF, 86 TF_UPDATE_TXN 87 ); 88 89 pub(crate) use uapi::{ 90 BINDER_TYPE_BINDER, BINDER_TYPE_FD, BINDER_TYPE_FDA, BINDER_TYPE_HANDLE, BINDER_TYPE_PTR, 91 BINDER_TYPE_WEAK_BINDER, BINDER_TYPE_WEAK_HANDLE, 92 }; 93 94 macro_rules! decl_wrapper { 95 ($newname:ident, $wrapped:ty) => { 96 // Define a wrapper around the C type. Use `MaybeUninit` to enforce that the value of 97 // padding bytes must be preserved. 98 #[derive(Copy, Clone)] 99 #[repr(transparent)] 100 pub(crate) struct $newname(MaybeUninit<$wrapped>); 101 102 // SAFETY: This macro is only used with types where this is ok. 103 unsafe impl FromBytes for $newname {} 104 unsafe impl AsBytes for $newname {} 105 106 impl Deref for $newname { 107 type Target = $wrapped; 108 fn deref(&self) -> &Self::Target { 109 // SAFETY: We use `MaybeUninit` only to preserve padding. The value must still 110 // always be valid. 111 unsafe { self.0.assume_init_ref() } 112 } 113 } 114 115 impl DerefMut for $newname { 116 fn deref_mut(&mut self) -> &mut Self::Target { 117 // SAFETY: We use `MaybeUninit` only to preserve padding. The value must still 118 // always be valid. 119 unsafe { self.0.assume_init_mut() } 120 } 121 } 122 123 impl Default for $newname { 124 fn default() -> Self { 125 // Create a new value of this type where all bytes (including padding) are zeroed. 126 Self(MaybeUninit::zeroed()) 127 } 128 } 129 }; 130 } 131 132 decl_wrapper!(BinderNodeDebugInfo, uapi::binder_node_debug_info); 133 decl_wrapper!(BinderNodeInfoForRef, uapi::binder_node_info_for_ref); 134 decl_wrapper!(FlatBinderObject, uapi::flat_binder_object); 135 decl_wrapper!(BinderFdObject, uapi::binder_fd_object); 136 decl_wrapper!(BinderFdArrayObject, uapi::binder_fd_array_object); 137 decl_wrapper!(BinderObjectHeader, uapi::binder_object_header); 138 decl_wrapper!(BinderBufferObject, uapi::binder_buffer_object); 139 decl_wrapper!(BinderTransactionData, uapi::binder_transaction_data); 140 decl_wrapper!( 141 BinderTransactionDataSecctx, 142 uapi::binder_transaction_data_secctx 143 ); 144 decl_wrapper!(BinderTransactionDataSg, uapi::binder_transaction_data_sg); 145 decl_wrapper!(BinderWriteRead, uapi::binder_write_read); 146 decl_wrapper!(BinderVersion, uapi::binder_version); 147 decl_wrapper!(BinderFrozenStatusInfo, uapi::binder_frozen_status_info); 148 decl_wrapper!(BinderFreezeInfo, uapi::binder_freeze_info); 149 decl_wrapper!(BinderFrozenStateInfo, uapi::binder_frozen_state_info); 150 decl_wrapper!(BinderHandleCookie, uapi::binder_handle_cookie); 151 decl_wrapper!(ExtendedError, uapi::binder_extended_error); 152 153 impl BinderVersion { current() -> Self154 pub(crate) fn current() -> Self { 155 Self(MaybeUninit::new(uapi::binder_version { 156 protocol_version: BINDER_CURRENT_PROTOCOL_VERSION as _, 157 })) 158 } 159 } 160 161 impl BinderTransactionData { with_buffers_size(self, buffers_size: u64) -> BinderTransactionDataSg162 pub(crate) fn with_buffers_size(self, buffers_size: u64) -> BinderTransactionDataSg { 163 BinderTransactionDataSg(MaybeUninit::new(uapi::binder_transaction_data_sg { 164 transaction_data: *self, 165 buffers_size, 166 })) 167 } 168 } 169 170 impl BinderTransactionDataSecctx { 171 /// View the inner data as wrapped in `BinderTransactionData`. tr_data(&mut self) -> &mut BinderTransactionData172 pub(crate) fn tr_data(&mut self) -> &mut BinderTransactionData { 173 // SAFETY: Transparent wrapper is safe to transmute. 174 unsafe { 175 &mut *(&mut self.transaction_data as *mut uapi::binder_transaction_data 176 as *mut BinderTransactionData) 177 } 178 } 179 } 180 181 impl ExtendedError { new(id: u32, command: u32, param: i32) -> Self182 pub(crate) fn new(id: u32, command: u32, param: i32) -> Self { 183 Self(MaybeUninit::new(uapi::binder_extended_error { 184 id, 185 command, 186 param, 187 })) 188 } 189 } 190