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