All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Pengfei Wang <wpengfeinudt@gmail.com>
Cc: Vaishali Thakkar <vaishali.thakkar@oracle.com>,
	Julia Lawall <julia.lawall@lip6.fr>,
	Vaishali Thakkar <vthakkar1994@gmail.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Michal Marek <mmarek@suse.com>,
	cocci@systeme.lip6.fr
Subject: Re: [Cocci] [PATCH] coccicheck: add a test for repeat copy_from_user
Date: Tue, 10 Jan 2017 11:15:46 -0800	[thread overview]
Message-ID: <CAGXu5j+eMfC-6rDpAT3jdxCoCQYiP1-BHMe8W1aQF7yxmgi9Hw@mail.gmail.com> (raw)
In-Reply-To: <05AE3A59-EF48-4FFF-A028-0204B2E56DEB@gmail.com>

On Tue, Jan 10, 2017 at 12:21 AM, Pengfei Wang <wpengfeinudt@gmail.com> wrote:
>
> 在 2017年1月10日,上午1:05,Vaishali Thakkar <vaishali.thakkar@oracle.com> 写道:
>
> On Tuesday 27 December 2016 11:51 PM, Julia Lawall wrote:
>
> I totally dropped the ball on this.  Many thanks to Vaishali for
> resurrecting it.
>
> Some changes are suggested below.
>
> On Tue, 26 Apr 2016, Kees Cook wrote:
>
> This is usually a sign of a resized request. This adds a check for
> potential races or confusions. The check isn't 100% accurate, so it
> needs some manual review.
>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
> scripts/coccinelle/tests/reusercopy.cocci | 36
> +++++++++++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
> create mode 100644 scripts/coccinelle/tests/reusercopy.cocci
>
> diff --git a/scripts/coccinelle/tests/reusercopy.cocci
> b/scripts/coccinelle/tests/reusercopy.cocci
> new file mode 100644
> index 000000000000..53645de8ae95
> --- /dev/null
> +++ b/scripts/coccinelle/tests/reusercopy.cocci
> @@ -0,0 +1,36 @@
> +/// Recopying from the same user buffer frequently indicates a pattern of
> +/// Reading a size header, allocating, and then re-reading an entire
> +/// structure. If the structure's size is not re-validated, this can lead
> +/// to structure or data size confusions.
> +///
> +// Confidence: Moderate
> +// Copyright: (C) 2016 Kees Cook, Google. License: GPLv2.
> +// URL: http://coccinelle.lip6.fr/
> +// Comments:
> +// Options: -no_includes -include_headers
>
>
> The options could be: --no-include --include-headers
>
> Actually, Coccinelle supports both, but it only officially supports the
> -- versions.
>
> +
> +virtual report
> +virtual org
>
>
> Add, the following for the *s:
>
> virtual context
>
> Then add the following rule:
>
> @ok@
> position p;
> expression src,dest;
> @@
>
> copy_from_user@p(&dest, src, sizeof(dest))
>
> +
> +@cfu_twice@
> +position p;
>
>
> Change this to:
>
> position p != ok.p;
>
> +identifier src;
> +expression dest1, dest2, size1, size2, offset;
> +@@
> +
> +*copy_from_user(dest1, src, size1)
> + ... when != src = offset
> +     when != src += offset
>
>
> Here, may be we should add few more lines from Pengfei's
> script to avoid th potential FPs.
>
> Add the following lines:
>
>     when != if (size2 > e1 || ...) { ... return ...; }
>     when != if (size2 > e1 || ...) { ... size2 = e2 ... }
>
> These changes drop cases where the last argument to copy_from_usr is the
> size of the first argument, which seems safe enough, and where there is a
> test on the size value that can either update it or abort the function.
> These changes only eliminate false positives, as far as I could tell.
>
> If it would be more convenient, I could just send the complete revised
> patch, or whatever seems convenient.
>
>
> I was also thinking that probably we should also add other user space memory
> API functions. May be get_user and strncpy_from_user. Although I'm not sure
> how common it is to find such patterns for both of these functions.
>
>
> I strongly recommend you adding get_user() API , which is used pervasively
> within the kernel just like copy_from user().
>
> In many situations, there is a combination use, get_user() copies first then
> followed by a copy_from_user() copy. According to our investigation, this
> typical
> situation works by get_user() firstly copying a field of a specific struct
> to check,
> then copy_from_user() copies in the whole struct to use. Of course, the
> struct
> field is fetch twice.

For sure, yes. I just split it out initially so we could compare some
of the pieces the two scripts do. Getting the size check into the test
was important to reduce false positives, so I think we need to just
expand the rules a bit more to include the size checks.

-Kees

-- 
Kees Cook
Nexus Security

WARNING: multiple messages have this Message-ID (diff)
From: keescook@chromium.org (Kees Cook)
To: cocci@systeme.lip6.fr
Subject: [Cocci] [PATCH] coccicheck: add a test for repeat copy_from_user
Date: Tue, 10 Jan 2017 11:15:46 -0800	[thread overview]
Message-ID: <CAGXu5j+eMfC-6rDpAT3jdxCoCQYiP1-BHMe8W1aQF7yxmgi9Hw@mail.gmail.com> (raw)
In-Reply-To: <05AE3A59-EF48-4FFF-A028-0204B2E56DEB@gmail.com>

On Tue, Jan 10, 2017 at 12:21 AM, Pengfei Wang <wpengfeinudt@gmail.com> wrote:
>
> ? 2017?1?10????1:05?Vaishali Thakkar <vaishali.thakkar@oracle.com> ???
>
> On Tuesday 27 December 2016 11:51 PM, Julia Lawall wrote:
>
> I totally dropped the ball on this.  Many thanks to Vaishali for
> resurrecting it.
>
> Some changes are suggested below.
>
> On Tue, 26 Apr 2016, Kees Cook wrote:
>
> This is usually a sign of a resized request. This adds a check for
> potential races or confusions. The check isn't 100% accurate, so it
> needs some manual review.
>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
> scripts/coccinelle/tests/reusercopy.cocci | 36
> +++++++++++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
> create mode 100644 scripts/coccinelle/tests/reusercopy.cocci
>
> diff --git a/scripts/coccinelle/tests/reusercopy.cocci
> b/scripts/coccinelle/tests/reusercopy.cocci
> new file mode 100644
> index 000000000000..53645de8ae95
> --- /dev/null
> +++ b/scripts/coccinelle/tests/reusercopy.cocci
> @@ -0,0 +1,36 @@
> +/// Recopying from the same user buffer frequently indicates a pattern of
> +/// Reading a size header, allocating, and then re-reading an entire
> +/// structure. If the structure's size is not re-validated, this can lead
> +/// to structure or data size confusions.
> +///
> +// Confidence: Moderate
> +// Copyright: (C) 2016 Kees Cook, Google. License: GPLv2.
> +// URL: http://coccinelle.lip6.fr/
> +// Comments:
> +// Options: -no_includes -include_headers
>
>
> The options could be: --no-include --include-headers
>
> Actually, Coccinelle supports both, but it only officially supports the
> -- versions.
>
> +
> +virtual report
> +virtual org
>
>
> Add, the following for the *s:
>
> virtual context
>
> Then add the following rule:
>
> @ok@
> position p;
> expression src,dest;
> @@
>
> copy_from_user at p(&dest, src, sizeof(dest))
>
> +
> + at cfu_twice@
> +position p;
>
>
> Change this to:
>
> position p != ok.p;
>
> +identifier src;
> +expression dest1, dest2, size1, size2, offset;
> +@@
> +
> +*copy_from_user(dest1, src, size1)
> + ... when != src = offset
> +     when != src += offset
>
>
> Here, may be we should add few more lines from Pengfei's
> script to avoid th potential FPs.
>
> Add the following lines:
>
>     when != if (size2 > e1 || ...) { ... return ...; }
>     when != if (size2 > e1 || ...) { ... size2 = e2 ... }
>
> These changes drop cases where the last argument to copy_from_usr is the
> size of the first argument, which seems safe enough, and where there is a
> test on the size value that can either update it or abort the function.
> These changes only eliminate false positives, as far as I could tell.
>
> If it would be more convenient, I could just send the complete revised
> patch, or whatever seems convenient.
>
>
> I was also thinking that probably we should also add other user space memory
> API functions. May be get_user and strncpy_from_user. Although I'm not sure
> how common it is to find such patterns for both of these functions.
>
>
> I strongly recommend you adding get_user() API , which is used pervasively
> within the kernel just like copy_from user().
>
> In many situations, there is a combination use, get_user() copies first then
> followed by a copy_from_user() copy. According to our investigation, this
> typical
> situation works by get_user() firstly copying a field of a specific struct
> to check,
> then copy_from_user() copies in the whole struct to use. Of course, the
> struct
> field is fetch twice.

For sure, yes. I just split it out initially so we could compare some
of the pieces the two scripts do. Getting the size check into the test
was important to reduce false positives, so I think we need to just
expand the rules a bit more to include the size checks.

-Kees

-- 
Kees Cook
Nexus Security

  parent reply	other threads:[~2017-01-10 19:16 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-26 22:24 [PATCH] coccicheck: add a test for repeat copy_from_user Kees Cook
2016-04-26 22:24 ` [Cocci] " Kees Cook
2016-04-26 22:30 ` Kees Cook
2016-04-26 22:30   ` [Cocci] " Kees Cook
2016-12-27 18:21 ` Julia Lawall
2016-12-27 18:21   ` [Cocci] " Julia Lawall
2017-01-02 15:45   ` Pengfei Wang
2017-01-09 17:05   ` Vaishali Thakkar
2017-01-09 17:05     ` Vaishali Thakkar
2017-01-09 19:08     ` Julia Lawall
2017-01-09 19:08       ` Julia Lawall
2017-01-09 20:56       ` Kees Cook
2017-01-09 20:56         ` Kees Cook
2017-01-09 22:02         ` Kees Cook
2017-01-09 22:02           ` Kees Cook
2017-01-10  8:21     ` Pengfei Wang
2017-01-10  8:40       ` Vaishali Thakkar
2017-01-10  8:40         ` Vaishali Thakkar
2017-01-10  9:02         ` Pengfei Wang
2017-01-10 17:46           ` Vaishali Thakkar
2017-01-10 17:46             ` Vaishali Thakkar
2017-01-11  2:10             ` Pengfei Wang
2017-01-11  6:10               ` Vaishali Thakkar
2017-01-11  6:12               ` Julia Lawall
2017-01-11  6:12                 ` Julia Lawall
2017-01-11 13:44                 ` Pengfei Wang
2017-01-11 13:44                   ` Pengfei Wang
2017-01-10 19:16         ` Kees Cook
2017-01-10 19:16           ` Kees Cook
2017-01-10 19:15       ` Kees Cook [this message]
2017-01-10 19:15         ` Kees Cook

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=CAGXu5j+eMfC-6rDpAT3jdxCoCQYiP1-BHMe8W1aQF7yxmgi9Hw@mail.gmail.com \
    --to=keescook@chromium.org \
    --cc=cocci@systeme.lip6.fr \
    --cc=julia.lawall@lip6.fr \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mmarek@suse.com \
    --cc=vaishali.thakkar@oracle.com \
    --cc=vthakkar1994@gmail.com \
    --cc=wpengfeinudt@gmail.com \
    /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.