lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sun, 4 Dec 2022 15:41:22 +0000
From:   "Dr. David Alan Gilbert" <dave@...blig.org>
To:     ojeda@...nel.org
Cc:     Wedson Almeida Filho <wedsonaf@...il.com>,
        Alex Gaynor <alex.gaynor@...il.com>,
        Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
        Björn Roy Baron <bjorn3_gh@...tonmail.com>,
        rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org,
        patches@...ts.linux.dev, Adam Bratschi-Kaye <ark.email@...il.com>
Subject: Re: [PATCH v2 20/28] rust: str: add `Formatter` type

* ojeda@...nel.org (ojeda@...nel.org) wrote:
> From: Wedson Almeida Filho <wedsonaf@...il.com>
> 
> Add the `Formatter` type, which leverages `RawFormatter`,
> but fails if callers attempt to write more than will fit
> in the buffer.
> 
> In order to so, implement the `RawFormatter::from_buffer()`
> constructor as well.
> 
> Co-developed-by: Adam Bratschi-Kaye <ark.email@...il.com>
> Signed-off-by: Adam Bratschi-Kaye <ark.email@...il.com>
> Signed-off-by: Wedson Almeida Filho <wedsonaf@...il.com>
> Reviewed-by: Gary Guo <gary@...yguo.net>
> [Reworded, adapted for upstream and applied latest changes]
> Signed-off-by: Miguel Ojeda <ojeda@...nel.org>
> ---
>  rust/kernel/str.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 57 insertions(+)
> 
> diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
> index a995db36486f..ce207d1b3d2a 100644
> --- a/rust/kernel/str.rs
> +++ b/rust/kernel/str.rs
> @@ -406,6 +406,23 @@ impl RawFormatter {
>          }
>      }
>  
> +    /// Creates a new instance of [`RawFormatter`] with the given buffer.
> +    ///
> +    /// # Safety
> +    ///
> +    /// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
> +    /// for the lifetime of the returned [`RawFormatter`].
> +    pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
> +        let pos = buf as usize;
> +        // INVARIANT: We ensure that `end` is never less then `buf`, and the safety requirements
> +        // guarantees that the memory region is valid for writes.
> +        Self {
> +            pos,
> +            beg: pos,
> +            end: pos.saturating_add(len),
> +        }
> +    }
> +
>      /// Returns the current insert position.
>      ///
>      /// N.B. It may point to invalid memory.
> @@ -439,3 +456,43 @@ impl fmt::Write for RawFormatter {
>          Ok(())
>      }
>  }
> +
> +/// Allows formatting of [`fmt::Arguments`] into a raw buffer.
> +///
> +/// Fails if callers attempt to write more than will fit in the buffer.
> +pub(crate) struct Formatter(RawFormatter);
> +
> +impl Formatter {
> +    /// Creates a new instance of [`Formatter`] with the given buffer.
> +    ///
> +    /// # Safety
> +    ///
> +    /// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
> +    /// for the lifetime of the returned [`Formatter`].
> +    #[allow(dead_code)]
> +    pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
> +        // SAFETY: The safety requirements of this function satisfy those of the callee.
> +        Self(unsafe { RawFormatter::from_buffer(buf, len) })
> +    }
> +}
> +
> +impl Deref for Formatter {
> +    type Target = RawFormatter;
> +
> +    fn deref(&self) -> &Self::Target {
> +        &self.0
> +    }
> +}
> +
> +impl fmt::Write for Formatter {
> +    fn write_str(&mut self, s: &str) -> fmt::Result {
> +        self.0.write_str(s)?;
> +
> +        // Fail the request if we go past the end of the buffer.

Reading this for the first time, I'm surprised by this, perhaps a
bit more comment is needed?  I was expecting that nothing would
let pos pass end.

Dave

> +        if self.0.pos > self.0.end {
> +            Err(fmt::Error)
> +        } else {
> +            Ok(())
> +        }
> +    }
> +}
> -- 
> 2.38.1
> 
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\        dave @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ