From: Boqun Feng <boqun.feng@gmail.com>
To: Alice Ryhl <aliceryhl@google.com>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
"Matthew Wilcox" <willy@infradead.org>,
"Al Viro" <viro@zeniv.linux.org.uk>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Kees Cook" <keescook@chromium.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Wedson Almeida Filho" <wedsonaf@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <benno.lossin@proton.me>,
"Andreas Hindborg" <a.hindborg@samsung.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Arve Hjønnevåg" <arve@android.com>,
"Todd Kjos" <tkjos@android.com>,
"Martijn Coenen" <maco@android.com>,
"Joel Fernandes" <joel@joelfernandes.org>,
"Carlos Llamas" <cmllamas@google.com>,
"Suren Baghdasaryan" <surenb@google.com>,
"Arnd Bergmann" <arnd@arndb.de>,
"Trevor Gross" <tmgross@umich.edu>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
rust-for-linux@vger.kernel.org,
"Christian Brauner" <brauner@kernel.org>
Subject: Re: [PATCH v6 1/4] rust: uaccess: add userspace pointers
Date: Fri, 19 Apr 2024 10:11:18 -0700 [thread overview]
Message-ID: <ZiKltinLGvKlBivm@boqun-archlinux> (raw)
In-Reply-To: <20240418-alice-mm-v6-1-cb8f3e5d688f@google.com>
On Thu, Apr 18, 2024 at 08:59:17AM +0000, Alice Ryhl wrote:
[...]
> + /// Reads the entirety of the user slice, appending it to the end of the provided buffer.
> + ///
> + /// Fails with `EFAULT` if the read happens on a bad address.
> + pub fn read_all(mut self, buf: &mut Vec<u8>, flags: Flags) -> Result {
> + let len = self.length;
> + buf.reserve(len, flags)?;
(Reportedy by Miguel)
When compile with `make rusttest`, kernel crate is compiled as userspace
program, so we need to explicitly pick where the `reserve` comes from
(Vec or VecExt), the current version will hit the following error:
error[E0061]: this method takes 1 argument but 2 arguments were supplied
--> rust/kernel/uaccess.rs:296:13
|
296 | buf.reserve(len, flags)?;
| ^^^^^^^ -------
| | |
| | unexpected argument of type `Flags`
| help: remove the extra argument
|
note: method defined here
--> /home/boqun/linux-rust/rust/test/sysroot/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:910:12
|
910 | pub fn reserve(&mut self, additional: usize) {
| ^^^^^^^
error[E0277]: the `?` operator can only be applied to values that implement `Try`
--> rust/kernel/uaccess.rs:296:9
|
296 | buf.reserve(len, flags)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `()`
|
= help: the trait `Try` is not implemented for `()`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0061, E0277.
For more information about an error, try `rustc --explain E0061`.
and we need to the following fix
diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
index 39481e374c40..80f7e7ca2f5e 100644
--- a/rust/kernel/uaccess.rs
+++ b/rust/kernel/uaccess.rs
@@ -293,7 +293,7 @@ pub fn read<T: FromBytes>(&mut self) -> Result<T> {
/// Fails with `EFAULT` if the read happens on a bad address.
pub fn read_all(mut self, buf: &mut Vec<u8>, flags: Flags) -> Result {
let len = self.length;
- buf.reserve(len, flags)?;
+ VecExt::<u8>::reserve(buf, len, flags)?;
// The call to `try_reserve` was successful, so the spare capacity is at least `len` bytes
// long.
Regards,
Boqun
> +
> + // The call to `try_reserve` was successful, so the spare capacity is at least `len` bytes
> + // long.
> + self.read_raw(&mut buf.spare_capacity_mut()[..len])?;
> +
> + // SAFETY: Since the call to `read_raw` was successful, so the next `len` bytes of the
> + // vector have been initialized.
> + unsafe { buf.set_len(buf.len() + len) };
> + Ok(())
> + }
> +}
> +
> +/// A writer for [`UserSlice`].
> +///
> +/// Used to incrementally write into the user slice.
> +pub struct UserSliceWriter {
> + ptr: UserPtr,
> + length: usize,
> +}
> +
> +impl UserSliceWriter {
> + /// Returns the amount of space remaining in this buffer.
> + ///
> + /// Note that even writing less than this number of bytes may fail.
> + pub fn len(&self) -> usize {
> + self.length
> + }
> +
> + /// Returns `true` if no more data can be written to this buffer.
> + pub fn is_empty(&self) -> bool {
> + self.length == 0
> + }
> +
> + /// Writes raw data to this user pointer from a kernel buffer.
> + ///
> + /// Fails with `EFAULT` if the write happens on a bad address, or if the write goes out of bounds
> + /// of this [`UserSliceWriter`]. This call may modify the associated userspace slice even if it
> + /// returns an error.
> + pub fn write_slice(&mut self, data: &[u8]) -> Result {
> + let len = data.len();
> + let data_ptr = data.as_ptr().cast::<c_void>();
> + if len > self.length {
> + return Err(EFAULT);
> + }
> + let Ok(len_ulong) = c_ulong::try_from(len) else {
> + return Err(EFAULT);
> + };
> + // SAFETY: `data_ptr` points into an immutable slice of length `len_ulong`, so we may read
> + // that many bytes from it.
> + let res = unsafe { bindings::copy_to_user(self.ptr as *mut c_void, data_ptr, len_ulong) };
> + if res != 0 {
> + return Err(EFAULT);
> + }
> + self.ptr = self.ptr.wrapping_add(len);
> + self.length -= len;
> + Ok(())
> + }
> +}
>
> --
> 2.44.0.683.g7961c838ac-goog
>
next prev parent reply other threads:[~2024-04-19 17:11 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-18 8:59 [PATCH v6 0/4] Memory management patches needed by Rust Binder Alice Ryhl
2024-04-18 8:59 ` [PATCH v6 1/4] rust: uaccess: add userspace pointers Alice Ryhl
2024-04-19 17:11 ` Boqun Feng [this message]
2024-04-19 18:12 ` Alice Ryhl
2024-04-18 8:59 ` [PATCH v6 2/4] uaccess: always export _copy_[from|to]_user with CONFIG_RUST Alice Ryhl
2024-05-14 17:27 ` Andrew Morton
2024-05-15 7:34 ` Arnd Bergmann
2024-04-18 8:59 ` [PATCH v6 3/4] rust: uaccess: add typed accessors for userspace pointers Alice Ryhl
2024-04-18 13:01 ` Benno Lossin
2024-04-18 13:17 ` Alice Ryhl
2024-04-18 16:23 ` Benno Lossin
2024-04-18 17:19 ` Boqun Feng
2024-04-18 19:35 ` Alice Ryhl
2024-04-18 20:01 ` Boqun Feng
2024-04-18 17:52 ` Trevor Gross
2024-04-25 16:13 ` Gary Guo
2024-04-26 7:13 ` Alice Ryhl
2024-04-18 8:59 ` [PATCH v6 4/4] rust: add abstraction for `struct page` Alice Ryhl
2024-04-18 18:52 ` Boqun Feng
2024-04-18 22:08 ` Benno Lossin
2024-04-18 22:56 ` Boqun Feng
2024-04-18 23:04 ` Boqun Feng
2024-04-19 8:36 ` Benno Lossin
2024-04-19 17:23 ` Boqun Feng
2024-04-19 19:24 ` Benno Lossin
2024-04-19 19:35 ` Boqun Feng
2024-04-25 16:20 ` Gary Guo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZiKltinLGvKlBivm@boqun-archlinux \
--to=boqun.feng@gmail.com \
--cc=a.hindborg@samsung.com \
--cc=akpm@linux-foundation.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=arnd@arndb.de \
--cc=arve@android.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=brauner@kernel.org \
--cc=cmllamas@google.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=joel@joelfernandes.org \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=maco@android.com \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=surenb@google.com \
--cc=tkjos@android.com \
--cc=tmgross@umich.edu \
--cc=viro@zeniv.linux.org.uk \
--cc=wedsonaf@gmail.com \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.