diff --git a/src/context/memory.rs b/src/context/memory.rs index 93446ba7a7..8ac4c43089 100644 --- a/src/context/memory.rs +++ b/src/context/memory.rs @@ -553,10 +553,14 @@ impl AddrSpaceWrapper { { Ok(_) => Ok(unsafe { RaiiFrame::new_unchecked(frame) }), Err(AddRefError::RcOverflow) => Err(Error::new(ENOMEM)), - Err(AddRefError::SharedToCow) => unreachable!(), - Err(AddRefError::CowToShared) => unreachable!( - "if it was CoW, it was read-only, but in that case we already called correct_inner" - ), + Err(AddRefError::SharedToCow) => { + log::error!("unexpected SharedToCow in add_ref — invariant violation"); + Err(Error::new(ENOMEM)) + } + Err(AddRefError::CowToShared) => { + log::error!("unexpected CowToShared in add_ref — invariant violation"); + Err(Error::new(ENOMEM)) + } }; drop(guard_lock); @@ -1499,7 +1503,10 @@ impl Grant { new_cow_frame }, - Err(AddRefError::SharedToCow) => unreachable!(), + Err(AddRefError::SharedToCow) => { + log::error!("unexpected SharedToCow in CoW path — invariant violation"); + return Err(Error::new(ENOMEM)); + }, Err(AddRefError::RcOverflow) => return Err(Error::new(ENOMEM)), } } else { @@ -2512,7 +2519,10 @@ fn correct_inner<'l>( if access == AccessMode::Write => { match faulting_pageinfo_opt { - Some((_, None)) => unreachable!("allocated page needs frame to be valid"), + Some((_, None)) => { + log::error!("allocated page has no frame — kernel invariant violation"); + return Err(Error::new(EINVAL)); + } Some((frame, Some(info))) => { if info.allows_writable() { frame @@ -2535,7 +2545,10 @@ fn correct_inner<'l>( Provider::Allocated { .. } | Provider::AllocatedShared { .. } => { match faulting_pageinfo_opt { - Some((_, None)) => unreachable!("allocated page needs frame to be valid"), + Some((_, None)) => { + log::error!("allocated page has no frame — kernel invariant violation"); + return Err(Error::new(EINVAL)); + } // TODO: Can this match arm even be reached? In other words, can the TLB cache // remember that pages are not present?