xref: /linux/drivers/android/binder/error.rs (revision 4f38da1f027ea2c9f01bb71daa7a299c191b6940)
1*eafedbc7SAlice Ryhl // SPDX-License-Identifier: GPL-2.0
2*eafedbc7SAlice Ryhl 
3*eafedbc7SAlice Ryhl // Copyright (C) 2025 Google LLC.
4*eafedbc7SAlice Ryhl 
5*eafedbc7SAlice Ryhl use kernel::prelude::*;
6*eafedbc7SAlice Ryhl 
7*eafedbc7SAlice Ryhl use crate::defs::*;
8*eafedbc7SAlice Ryhl 
9*eafedbc7SAlice Ryhl pub(crate) type BinderResult<T = ()> = core::result::Result<T, BinderError>;
10*eafedbc7SAlice Ryhl 
11*eafedbc7SAlice Ryhl /// An error that will be returned to userspace via the `BINDER_WRITE_READ` ioctl rather than via
12*eafedbc7SAlice Ryhl /// errno.
13*eafedbc7SAlice Ryhl pub(crate) struct BinderError {
14*eafedbc7SAlice Ryhl     pub(crate) reply: u32,
15*eafedbc7SAlice Ryhl     source: Option<Error>,
16*eafedbc7SAlice Ryhl }
17*eafedbc7SAlice Ryhl 
18*eafedbc7SAlice Ryhl impl BinderError {
19*eafedbc7SAlice Ryhl     pub(crate) fn new_dead() -> Self {
20*eafedbc7SAlice Ryhl         Self {
21*eafedbc7SAlice Ryhl             reply: BR_DEAD_REPLY,
22*eafedbc7SAlice Ryhl             source: None,
23*eafedbc7SAlice Ryhl         }
24*eafedbc7SAlice Ryhl     }
25*eafedbc7SAlice Ryhl 
26*eafedbc7SAlice Ryhl     pub(crate) fn new_frozen() -> Self {
27*eafedbc7SAlice Ryhl         Self {
28*eafedbc7SAlice Ryhl             reply: BR_FROZEN_REPLY,
29*eafedbc7SAlice Ryhl             source: None,
30*eafedbc7SAlice Ryhl         }
31*eafedbc7SAlice Ryhl     }
32*eafedbc7SAlice Ryhl 
33*eafedbc7SAlice Ryhl     pub(crate) fn new_frozen_oneway() -> Self {
34*eafedbc7SAlice Ryhl         Self {
35*eafedbc7SAlice Ryhl             reply: BR_TRANSACTION_PENDING_FROZEN,
36*eafedbc7SAlice Ryhl             source: None,
37*eafedbc7SAlice Ryhl         }
38*eafedbc7SAlice Ryhl     }
39*eafedbc7SAlice Ryhl 
40*eafedbc7SAlice Ryhl     pub(crate) fn is_dead(&self) -> bool {
41*eafedbc7SAlice Ryhl         self.reply == BR_DEAD_REPLY
42*eafedbc7SAlice Ryhl     }
43*eafedbc7SAlice Ryhl 
44*eafedbc7SAlice Ryhl     pub(crate) fn as_errno(&self) -> kernel::ffi::c_int {
45*eafedbc7SAlice Ryhl         self.source.unwrap_or(EINVAL).to_errno()
46*eafedbc7SAlice Ryhl     }
47*eafedbc7SAlice Ryhl 
48*eafedbc7SAlice Ryhl     pub(crate) fn should_pr_warn(&self) -> bool {
49*eafedbc7SAlice Ryhl         self.source.is_some()
50*eafedbc7SAlice Ryhl     }
51*eafedbc7SAlice Ryhl }
52*eafedbc7SAlice Ryhl 
53*eafedbc7SAlice Ryhl /// Convert an errno into a `BinderError` and store the errno used to construct it. The errno
54*eafedbc7SAlice Ryhl /// should be stored as the thread's extended error when given to userspace.
55*eafedbc7SAlice Ryhl impl From<Error> for BinderError {
56*eafedbc7SAlice Ryhl     fn from(source: Error) -> Self {
57*eafedbc7SAlice Ryhl         Self {
58*eafedbc7SAlice Ryhl             reply: BR_FAILED_REPLY,
59*eafedbc7SAlice Ryhl             source: Some(source),
60*eafedbc7SAlice Ryhl         }
61*eafedbc7SAlice Ryhl     }
62*eafedbc7SAlice Ryhl }
63*eafedbc7SAlice Ryhl 
64*eafedbc7SAlice Ryhl impl From<kernel::fs::file::BadFdError> for BinderError {
65*eafedbc7SAlice Ryhl     fn from(source: kernel::fs::file::BadFdError) -> Self {
66*eafedbc7SAlice Ryhl         BinderError::from(Error::from(source))
67*eafedbc7SAlice Ryhl     }
68*eafedbc7SAlice Ryhl }
69*eafedbc7SAlice Ryhl 
70*eafedbc7SAlice Ryhl impl From<kernel::alloc::AllocError> for BinderError {
71*eafedbc7SAlice Ryhl     fn from(_: kernel::alloc::AllocError) -> Self {
72*eafedbc7SAlice Ryhl         Self {
73*eafedbc7SAlice Ryhl             reply: BR_FAILED_REPLY,
74*eafedbc7SAlice Ryhl             source: Some(ENOMEM),
75*eafedbc7SAlice Ryhl         }
76*eafedbc7SAlice Ryhl     }
77*eafedbc7SAlice Ryhl }
78*eafedbc7SAlice Ryhl 
79*eafedbc7SAlice Ryhl impl core::fmt::Debug for BinderError {
80*eafedbc7SAlice Ryhl     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81*eafedbc7SAlice Ryhl         match self.reply {
82*eafedbc7SAlice Ryhl             BR_FAILED_REPLY => match self.source.as_ref() {
83*eafedbc7SAlice Ryhl                 Some(source) => f
84*eafedbc7SAlice Ryhl                     .debug_struct("BR_FAILED_REPLY")
85*eafedbc7SAlice Ryhl                     .field("source", source)
86*eafedbc7SAlice Ryhl                     .finish(),
87*eafedbc7SAlice Ryhl                 None => f.pad("BR_FAILED_REPLY"),
88*eafedbc7SAlice Ryhl             },
89*eafedbc7SAlice Ryhl             BR_DEAD_REPLY => f.pad("BR_DEAD_REPLY"),
90*eafedbc7SAlice Ryhl             BR_FROZEN_REPLY => f.pad("BR_FROZEN_REPLY"),
91*eafedbc7SAlice Ryhl             BR_TRANSACTION_PENDING_FROZEN => f.pad("BR_TRANSACTION_PENDING_FROZEN"),
92*eafedbc7SAlice Ryhl             BR_TRANSACTION_COMPLETE => f.pad("BR_TRANSACTION_COMPLETE"),
93*eafedbc7SAlice Ryhl             _ => f
94*eafedbc7SAlice Ryhl                 .debug_struct("BinderError")
95*eafedbc7SAlice Ryhl                 .field("reply", &self.reply)
96*eafedbc7SAlice Ryhl                 .finish(),
97*eafedbc7SAlice Ryhl         }
98*eafedbc7SAlice Ryhl     }
99*eafedbc7SAlice Ryhl }
100