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