From 99975c0e42e1ee8f2172cd94c408296b42d5f85d Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Thu, 29 Jun 2023 11:47:52 +0200 Subject: [PATCH] WIP: Ensure that Grant::borrow does not borrow nonpresent grants. --- src/context/memory.rs | 26 +++++++++++++++++++++----- src/lib.rs | 1 + 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/context/memory.rs b/src/context/memory.rs index ffc61415..2c649285 100644 --- a/src/context/memory.rs +++ b/src/context/memory.rs @@ -644,7 +644,7 @@ impl Grant { dst_mapper: &mut PageMapper, dst_flusher: impl Flusher<RmmA>, eager: bool, - ) -> Result<Vec<Grant>, Enomem> { + ) -> Result<Vec<Grant>> { /* if eager { for page in PageSpan::new(src_base, page_count) { @@ -653,16 +653,22 @@ impl Grant { } */ - // TODO: If grants are missing for certain ranges specified, fill with Provider::External - // grants anyway, which will in turn fill the host address space will zeroed grants. This - // is required before schemes can be safe. - let mut dst_grants = Vec::with_capacity(1); let src_span = PageSpan::new(src_base, page_count); + let mut prev_span = None; for (src_grant_base, src_grant) in src_address_space.grants.conflicts(src_span) { let grant_span = PageSpan::new(src_grant_base, src_grant.page_count); + let prev_span = prev_span.replace(grant_span); + + if prev_span.is_none() && src_grant_base > src_base { + log::warn!("Grant too far away, prev_span {:?} src_base {:?} grant base {:?} grant {:#?}", prev_span, src_base, src_grant_base, src_grant); + return Err(Error::new(EINVAL)); + } else if let Some(prev) = prev_span && prev.end() != src_grant_base { + log::warn!("Hole between grants, prev_span {:?} src_base {:?} grant base {:?} grant {:#?}", prev_span, src_base, src_grant_base, src_grant); + return Err(Error::new(EINVAL)); + } let common_span = src_span.intersection(grant_span); let offset_from_src_base = common_span.base.offset_from(src_base); @@ -690,6 +696,16 @@ impl Grant { }); } + let Some(last_span) = prev_span else { + log::warn!("Called Grant::borrow, but no grants were there!"); + return Err(Error::new(EINVAL)); + }; + + if last_span.end() < src_span.end() { + log::warn!("Requested end page too far away from last grant"); + return Err(Error::new(EINVAL)); + } + Ok(dst_grants) } // TODO: This is limited to one grant. Should it be (if some magic new proc: API is introduced)? diff --git a/src/lib.rs b/src/lib.rs index 94be6424..b6312060 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,7 @@ #![feature(const_option)] #![feature(arbitrary_self_types)] #![feature(int_roundings)] +#![feature(let_chains)] #![feature(naked_functions)] #![feature(slice_ptr_get, slice_ptr_len)] #![feature(sync_unsafe_cell)] -- GitLab