xref: /linux/drivers/android/binder/defs.rs (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
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