[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHk-=winQ_607Sp09H1w70A_WPmt7ydxrNrwvk=N29S=FpASZw@mail.gmail.com>
Date: Wed, 22 Jan 2020 12:00:31 -0800
From: Linus Torvalds <torvalds@...ux-foundation.org>
To: Christophe Leroy <christophe.leroy@....fr>
Cc: Benjamin Herrenschmidt <benh@...nel.crashing.org>,
Paul Mackerras <paulus@...ba.org>,
Michael Ellerman <mpe@...erman.id.au>,
Alexander Viro <viro@...iv.linux.org.uk>,
Andrew Morton <akpm@...ux-foundation.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
linuxppc-dev <linuxppc-dev@...ts.ozlabs.org>,
linux-fsdevel <linux-fsdevel@...r.kernel.org>,
Linux-MM <linux-mm@...ck.org>
Subject: Re: [PATCH v2 1/6] fs/readdir: Fix filldir() and filldir64() use of user_access_begin()
On Wed, Jan 22, 2020 at 10:24 AM Linus Torvalds
<torvalds@...ux-foundation.org> wrote:
>
> Patch looks better, but those names are horrid.
Hmm.
A bit more re-organization also allows us to do the unsafe_put_user()
unconditionally.
In particular, if we remove 'previous' as a pointer from the filldir
data structure, and replace it with 'prev_reclen', then we can do
prev_reclen = buf->prev_reclen;
dirent = buf->current_dir;
prev = (void __user *) dirent - prev_reclen;
if (!user_access_begin(prev, reclen + prev_reclen))
goto efault;
and instead of checking that 'previous' pointer for NULL, we just
check prev_reclen for not being zero.
Yes, it replaces a few other
lastdirent = buf.previous;
with the slightly more complicated
lastdirent = (void __user *)buf.current_dir - buf.prev_reclen;
but on the whole it makes the _important_ code more streamlined, and
avoids having to have those if-else cases.
Something like the attached.
COMPLETELY UNTESTED! It compiles for me. The generated assembly looks
ok from a quick look.
Christophe, does this work for you on your ppc test-case?
Side note: I think verify_dirent_name() should check that 'len' is in
the appropriate range too, because right now a corrupted filesystem is
only noticed for a zero length. But a negative one, or one where the
reclen calculations would overflow, is not noticed.
Most filesystems have the source of 'len' being something like an
'unsigned char' so that it's pretty bounded anyway, which is likely
why nobody cared when we added that check, but..
Linus
View attachment "patch.diff" of type "text/x-patch" (5989 bytes)
Powered by blists - more mailing lists