Re: [PATCH v4 2/2] uaccess: rust: add UserSliceReader::strcpy_into_buf
From: Alice Ryhl
Date: Mon Jun 02 2025 - 04:30:59 EST
On Sun, Jun 01, 2025 at 06:09:26PM +0200, Benno Lossin wrote:
> On Sat May 31, 2025 at 11:09 PM CEST, Alice Ryhl wrote:
> > On Sat, May 31, 2025 at 10:38 PM Benno Lossin <lossin@xxxxxxxxxx> wrote:
> >> Maybe I misunderstood the code, but if you do this:
> >>
> >> let slice = UserSlice::new(ptr, 1024);
> >> let mut buf = [0; 42];
> >> let s = slice.strcpy_into_buf(&mut buf)?;
> >>
> >> Then it will read 42 characters from userspace and (if there was no nul
> >> byte) overwrite the last character with `\0`. If we now do
> >>
> >> let mut buf2 = [0; 42];
> >> let s2 = slice.strcpy_into_buf(&mut buf2)?;
> >>
> >> Then that will continue the read at index 42, but effectively one
> >> character will get skipped.
> >>
> >> (Now it's not possible to call `strcpy_into_buf` multiple times, but I
> >> see no real reason why it isn't a `&mut self` method. Also a user could
> >> call `clone_reader` and then manually `skip` 42 bytes. Although they
> >> might only skip 41 bytes, since that's the length of the CStr. But that
> >> runs into the problem that if there was a `\0` at index 41, then
> >> repeated uses of the pattern above will yield empty strings.)
> >
> > I removed the ability to call it multiple times to avoid dealing with
> > this kind of question. You may submit a follow-up patch to change it
> > if you have a use-case.
>
> I don't have a use-case, but we should document this behavior somewhere
> especially since the ability to only call this function once guarantees
> the correctness.
I'll add a comment, though I would note that what we pass to
strncpy_from_user isn't really relevant here, even if the method was
&mut self. In that case, the thing that matters is how much we change
self.length by.
Alice