1 // Copyright 2023, The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //! Error types used in libgbl. 16 17 use crate::GblOpsError; 18 use avb::{DescriptorError, SlotVerifyError}; 19 use core::ffi::{FromBytesUntilNulError, FromBytesWithNulError}; 20 use core::fmt::{Debug, Display, Formatter}; 21 use gbl_storage::StorageError; 22 23 /// Helper type GBL functions will return. 24 pub type Result<T> = core::result::Result<T, IntegrationError>; 25 26 #[derive(Debug, PartialEq, Eq)] 27 /// Errors originating from GBL native logic. 28 pub enum Error { 29 ArithmeticOverflow, 30 /// Fail to hand off to kernel. 31 BootFailed, 32 /// Generic error 33 Error, 34 /// Missing all images required to boot system 35 MissingImage, 36 /// Functionality is not implemented 37 NotImplemented, 38 /// Some combination of parameters and global state prohibits the operation 39 OperationProhibited, 40 /// Internal error 41 Internal, 42 /// AvbOps were already borrowed. This would happen on second `load_and_verify_image()` call 43 /// unless `reuse()` is called before. 44 AvbOpsBusy, 45 /// Buffers overlap and can cause undefined behavior and data corruption. 46 BufferOverlap, 47 } 48 49 impl Display for Error { fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result50 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { 51 match self { 52 Error::ArithmeticOverflow => write!(f, "Arithmetic Overflow"), 53 Error::BootFailed => write!(f, "Failed to boot"), 54 Error::Error => write!(f, "Generic error"), 55 Error::MissingImage => write!(f, "Missing image required to boot system"), 56 Error::NotImplemented => write!(f, "Functionality is not implemented"), 57 Error::OperationProhibited => write!(f, "Operation is prohibited"), 58 Error::Internal => write!(f, "Internal error"), 59 Error::AvbOpsBusy => write!(f, "AvbOps were already borrowed"), 60 Error::BufferOverlap => write!(f, "Buffers overlap"), 61 } 62 } 63 } 64 65 /// A helper macro for declaring a composite enum type that simply wraps other types as entries. 66 /// It auto-generate `From<...>` implementation for each entry type. The type for each entry must 67 /// be different from each other. i.e.: 68 /// 69 /// ```rust 70 /// composite_enum! { 71 /// pub enum MyEnum { 72 /// Usize(usize), 73 /// I64(i64), 74 /// } 75 /// } 76 /// ``` 77 /// 78 /// expands to 79 /// 80 /// ```rust 81 /// pub enum MyEnum { 82 /// Usize(usize), 83 /// I64(i64), 84 /// } 85 /// 86 /// impl From<usize> for MyEnum { 87 /// fn from(ent: usize) -> MyEnum { 88 /// MyEnum::Usize(ent) 89 /// } 90 /// } 91 /// 92 /// impl From<i64> for MyEnum { 93 /// fn from(ent: i64) -> MyEnum { 94 /// MyEnum::I64(ent) 95 /// } 96 /// } 97 /// ``` 98 #[macro_export] 99 macro_rules! composite_enum { 100 ( 101 $(#[$outer:meta])* 102 $vis:vis enum $name:ident { 103 $( 104 $(#[$inner:ident $($args:tt)*])* 105 $ent:ident($ent_t:ty) 106 ),* 107 $(,)* 108 } 109 ) => { 110 // Copy over enum declaration as it is. 111 $(#[$outer])* 112 $vis enum $name { 113 $( 114 $(#[$inner $($args)*])* 115 $ent($ent_t) 116 ),* 117 } 118 119 // Generate `From<...>` implementation. 120 composite_enum!{$name, $($ent($ent_t)),*} 121 }; 122 // `From<>` implementation generation. Base case. 123 ($name:ident, $ent:ident($ent_t:ty)) => { 124 impl From<$ent_t> for $name { 125 fn from(ent: $ent_t) -> $name { 126 $name::$ent(ent) 127 } 128 } 129 }; 130 // `From<>` implementation generation. Recursive case. 131 ($name:ident, $ent:ident($ent_t:ty), $($next:ident($next_t:ty)),+) => { 132 composite_enum!{$name, $ent($ent_t)} 133 composite_enum!{$name, $($next($next_t)),*} 134 }; 135 } 136 137 composite_enum! { 138 /// Top level error type that integrates errors from various dependency libraries. 139 #[derive(Debug, PartialEq, Eq)] 140 pub enum IntegrationError { 141 /// Failed to get descriptor from AvbMeta 142 AvbDescriptorError(DescriptorError), 143 /// Avb slot verification failed. 144 /// SlotVerifyError is used without verify data. 145 AvbSlotVerifyError(SlotVerifyError<'static>), 146 GblNativeError(Error), 147 GblOpsError(GblOpsError), 148 FromBytesUntilNulError(FromBytesUntilNulError), 149 FromBytesWithNulError(FromBytesWithNulError), 150 StorageError(StorageError), 151 SafeMathError(safemath::Error), 152 } 153 } 154 155 impl Display for IntegrationError { fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result156 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { 157 write!(f, "{:?}", self) 158 } 159 } 160