1 // SPDX-License-Identifier: GPL-2.0 2 3 // Copyright (C) 2025 Google LLC. 4 5 use core::mem::MaybeUninit; 6 use core::ops::{Deref, DerefMut}; 7 use kernel::{ 8 transmute::{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_flags_, 69 FLAT_BINDER_FLAG_ACCEPTS_FDS, 70 FLAT_BINDER_FLAG_TXN_SECURITY_CTX 71 ); 72 73 pub_no_prefix!( 74 transaction_flags_, 75 TF_ONE_WAY, 76 TF_ACCEPT_FDS, 77 TF_CLEAR_BUF, 78 TF_UPDATE_TXN 79 ); 80 81 pub(crate) use uapi::{ 82 BINDER_TYPE_BINDER, BINDER_TYPE_FD, BINDER_TYPE_FDA, BINDER_TYPE_HANDLE, BINDER_TYPE_PTR, 83 BINDER_TYPE_WEAK_BINDER, BINDER_TYPE_WEAK_HANDLE, 84 }; 85 86 macro_rules! decl_wrapper { 87 ($newname:ident, $wrapped:ty) => { 88 // Define a wrapper around the C type. Use `MaybeUninit` to enforce that the value of 89 // padding bytes must be preserved. 90 #[derive(Copy, Clone)] 91 #[repr(transparent)] 92 pub(crate) struct $newname(MaybeUninit<$wrapped>); 93 94 // SAFETY: This macro is only used with types where this is ok. 95 unsafe impl FromBytes for $newname {} 96 // SAFETY: This macro is only used with types where this is ok. 97 unsafe impl AsBytes for $newname {} 98 99 impl Deref for $newname { 100 type Target = $wrapped; 101 fn deref(&self) -> &Self::Target { 102 // SAFETY: We use `MaybeUninit` only to preserve padding. The value must still 103 // always be valid. 104 unsafe { self.0.assume_init_ref() } 105 } 106 } 107 108 impl DerefMut for $newname { 109 fn deref_mut(&mut self) -> &mut Self::Target { 110 // SAFETY: We use `MaybeUninit` only to preserve padding. The value must still 111 // always be valid. 112 unsafe { self.0.assume_init_mut() } 113 } 114 } 115 116 impl Default for $newname { 117 fn default() -> Self { 118 // Create a new value of this type where all bytes (including padding) are zeroed. 119 Self(MaybeUninit::zeroed()) 120 } 121 } 122 }; 123 } 124 125 decl_wrapper!(BinderNodeDebugInfo, uapi::binder_node_debug_info); 126 decl_wrapper!(BinderNodeInfoForRef, uapi::binder_node_info_for_ref); 127 decl_wrapper!(FlatBinderObject, uapi::flat_binder_object); 128 decl_wrapper!(BinderFdObject, uapi::binder_fd_object); 129 decl_wrapper!(BinderFdArrayObject, uapi::binder_fd_array_object); 130 decl_wrapper!(BinderObjectHeader, uapi::binder_object_header); 131 decl_wrapper!(BinderBufferObject, uapi::binder_buffer_object); 132 decl_wrapper!(BinderTransactionData, uapi::binder_transaction_data); 133 decl_wrapper!( 134 BinderTransactionDataSecctx, 135 uapi::binder_transaction_data_secctx 136 ); 137 decl_wrapper!(BinderTransactionDataSg, uapi::binder_transaction_data_sg); 138 decl_wrapper!(BinderWriteRead, uapi::binder_write_read); 139 decl_wrapper!(BinderVersion, uapi::binder_version); 140 decl_wrapper!(BinderFrozenStatusInfo, uapi::binder_frozen_status_info); 141 decl_wrapper!(BinderFreezeInfo, uapi::binder_freeze_info); 142 decl_wrapper!(BinderFrozenStateInfo, uapi::binder_frozen_state_info); 143 decl_wrapper!(BinderHandleCookie, uapi::binder_handle_cookie); 144 decl_wrapper!(ExtendedError, uapi::binder_extended_error); 145 146 impl BinderVersion { 147 pub(crate) fn current() -> Self { 148 Self(MaybeUninit::new(uapi::binder_version { 149 protocol_version: BINDER_CURRENT_PROTOCOL_VERSION as _, 150 })) 151 } 152 } 153 154 impl BinderTransactionData { 155 pub(crate) fn with_buffers_size(self, buffers_size: u64) -> BinderTransactionDataSg { 156 BinderTransactionDataSg(MaybeUninit::new(uapi::binder_transaction_data_sg { 157 transaction_data: *self, 158 buffers_size, 159 })) 160 } 161 } 162 163 impl BinderTransactionDataSecctx { 164 /// View the inner data as wrapped in `BinderTransactionData`. 165 pub(crate) fn tr_data(&mut self) -> &mut BinderTransactionData { 166 // SAFETY: Transparent wrapper is safe to transmute. 167 unsafe { 168 &mut *(&mut self.transaction_data as *mut uapi::binder_transaction_data 169 as *mut BinderTransactionData) 170 } 171 } 172 } 173 174 impl ExtendedError { 175 pub(crate) fn new(id: u32, command: u32, param: i32) -> Self { 176 Self(MaybeUninit::new(uapi::binder_extended_error { 177 id, 178 command, 179 param, 180 })) 181 } 182 } 183