From: Kees Cook <keescook@chromium.org>
To: Arnd Bergmann <arnd@arndb.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>,
Christian Brauner <christian@brauner.io>,
Rasmus Villemoes <linux@rasmusvillemoes.dk>,
Dinh Nguyen <dinguyen@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Andrew Morton <akpm@linux-foundation.org>,
Geert Uytterhoeven <geert@linux-m68k.org>,
Alexander Potapenko <glider@google.com>,
Christian Brauner <brauner@kernel.org>,
Stafford Horne <shorne@gmail.com>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Christophe Leroy <christophe.leroy@csgroup.eu>,
linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: Re: [PATCH] uaccess: Add minimum bounds check on kernel buffer size
Date: Fri, 3 Feb 2023 22:27:54 +0000 [thread overview]
Message-ID: <63dd8a6b.170a0220.f5c98.9e65@mx.google.com> (raw)
In-Reply-To: <6c728dfc-d777-4beb-b463-649704c81a5e@app.fastmail.com>
On Fri, Feb 03, 2023 at 10:23:13PM +0100, Arnd Bergmann wrote:
> On Fri, Feb 3, 2023, at 20:35, Kees Cook wrote:
> > While there is logic about the difference between ksize and usize,
> > copy_struct_from_user() didn't check the size of the destination buffer
> > (when it was known) against ksize. Add this check so there is an upper
> > bounds check on the possible memset() call, otherwise lower bounds
> > checks made by callers will trigger bounds warnings under -Warray-bounds.
> > Seen under GCC 13:
> >
> > In function 'copy_struct_from_user',
> > inlined from 'iommufd_fops_ioctl' at
> > ../drivers/iommu/iommufd/main.c:333:8:
> > ../include/linux/fortify-string.h:59:33: warning: '__builtin_memset'
> > offset [57, 4294967294] is out of the bounds [0, 56] of object 'buf'
> > with type 'union ucmd_buffer' [-Warray-bounds=]
> > 59 | #define __underlying_memset __builtin_memset
> > | ^
> > ../include/linux/fortify-string.h:453:9: note: in expansion of macro
> > '__underlying_memset'
> > 453 | __underlying_memset(p, c, __fortify_size); \
> > | ^~~~~~~~~~~~~~~~~~~
> > ../include/linux/fortify-string.h:461:25: note: in expansion of macro
> > '__fortify_memset_chk'
> > 461 | #define memset(p, c, s) __fortify_memset_chk(p, c, s, \
> > | ^~~~~~~~~~~~~~~~~~~~
> > ../include/linux/uaccess.h:334:17: note: in expansion of macro 'memset'
> > 334 | memset(dst + size, 0, rest);
> > | ^~~~~~
> > ../drivers/iommu/iommufd/main.c: In function 'iommufd_fops_ioctl':
> > ../drivers/iommu/iommufd/main.c:311:27: note: 'buf' declared here
> > 311 | union ucmd_buffer buf;
> > | ^~~
> >
>
> Hi Kees,
>
> I started building with gcc-13.0.1 myself but ran into a lot of
> other -Warray-bounds warnings in randconfig builds, so I ended up
> turning it off once more with CONFIG_CC_NO_ARRAY_BOUNDS in order
> to keep building without warnings.
Understood. AFAIK, all the open bugs I (and you) filed with GCC 13 have
been fixed related to -Warray-bounds. The most recent was the misbehavior
between CONFIG_UBSAN_SHIFT and -Warray-bounds. (Though the shift checking
still exposes some warnings since it introduces an implicit bounds check
on the shift variable, but they're not _wrong_ any more.)
> Is there anything else I need to do to get to the point of
> just addressing actual issues instead of false positives?
> Do you already have a patch series for fixing the others?
I've been working through the list that I see when building with
-Warray-bounds and -fstrict-flex-arrays=3. Some are real bugs, as usual.
> > diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
> > index afb18f198843..ab9728138ad6 100644
> > --- a/include/linux/uaccess.h
> > +++ b/include/linux/uaccess.h
> > @@ -329,6 +329,10 @@ copy_struct_from_user(void *dst, size_t ksize,
> > const void __user *src,
> > size_t size = min(ksize, usize);
> > size_t rest = max(ksize, usize) - size;
> >
> > + /* Double check if ksize is larger than a known object size. */
> > + if (WARN_ON_ONCE(ksize > __builtin_object_size(dst, 1)))
> > + return -E2BIG;
> > +
>
> WARN_ON_ONCE() may be a little expensive since that adds two
> comparisons and a static variable to each copy, but it's probably
> fine.
Yeah. IMO, copy_struct_from_user() is not fast path and having better
bounds checking when coming from userspace is well worth it.
--
Kees Cook
next prev parent reply other threads:[~2023-02-03 22:28 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-03 19:35 [PATCH] uaccess: Add minimum bounds check on kernel buffer size Kees Cook
2023-02-03 21:23 ` Arnd Bergmann
2023-02-03 22:01 ` Arnd Bergmann
2023-02-03 22:27 ` Kees Cook [this message]
2023-02-06 20:03 ` Geert Uytterhoeven
2023-02-06 21:32 ` Kees Cook
[not found] ` <CAMuHMdXXSwYYoUMskhcgjF9SVjraZC-UsBT3sN+xkcUAYmJj4Q-2143@mail.gmail.com>
2023-02-07 9:06 ` Yann Droneaud
2023-02-07 23:28 ` Kees Cook
2023-02-08 5:48 ` Aleksa Sarai
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=63dd8a6b.170a0220.f5c98.9e65@mx.google.com \
--to=keescook@chromium.org \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=brauner@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=christian@brauner.io \
--cc=christophe.leroy@csgroup.eu \
--cc=cyphar@cyphar.com \
--cc=dinguyen@kernel.org \
--cc=geert@linux-m68k.org \
--cc=glider@google.com \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=shorne@gmail.com \
--cc=viro@zeniv.linux.org.uk \
/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.