public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Andrew Pinski <pinskia@gmail.com>
To: Kees Cook <keescook@chromium.org>
Cc: Jeff Law <jeffreyalaw@gmail.com>,
	Qing Zhao <qing.zhao@oracle.com>,
	 GCC Patches <gcc-patches@gcc.gnu.org>,
	Richard Guenther <rguenther@suse.de>
Subject: Re: [RFC][PATCH] PR tree-optimization/109071 - -Warray-bounds false positive warnings due to code duplication from jump threading
Date: Tue, 14 May 2024 01:38:49 +0200	[thread overview]
Message-ID: <CA+=Sn1mGaP5mH5y9HCjqgdbNdBeQBYtrJfnBagFCLyqioyKCpw@mail.gmail.com> (raw)
In-Reply-To: <202405131428.5CFEDA3@keescook>

[-- Attachment #1: Type: text/plain, Size: 5704 bytes --]

On Mon, May 13, 2024, 11:41 PM Kees Cook <keescook@chromium.org> wrote:

> On Mon, May 13, 2024 at 02:46:32PM -0600, Jeff Law wrote:
> >
> >
> > On 5/13/24 1:48 PM, Qing Zhao wrote:
> > > -Warray-bounds is an important option to enable linux kernal to keep
> > > the array out-of-bound errors out of the source tree.
> > >
> > > However, due to the false positive warnings reported in PR109071
> > > (-Warray-bounds false positive warnings due to code duplication from
> > > jump threading), -Warray-bounds=1 cannot be added on by default.
> > >
> > > Although it's impossible to elinimate all the false positive warnings
> > > from -Warray-bounds=1 (See PR104355 Misleading -Warray-bounds
> > > documentation says "always out of bounds"), we should minimize the
> > > false positive warnings in -Warray-bounds=1.
> > >
> > > The root reason for the false positive warnings reported in PR109071
> is:
> > >
> > > When the thread jump optimization tries to reduce the # of branches
> > > inside the routine, sometimes it needs to duplicate the code and
> > > split into two conditional pathes. for example:
> > >
> > > The original code:
> > >
> > > void sparx5_set (int * ptr, struct nums * sg, int index)
> > > {
> > >    if (index >= 4)
> > >      warn ();
> > >    *ptr = 0;
> > >    *val = sg->vals[index];
> > >    if (index >= 4)
> > >      warn ();
> > >    *ptr = *val;
> > >
> > >    return;
> > > }
> > >
> > > With the thread jump, the above becomes:
> > >
> > > void sparx5_set (int * ptr, struct nums * sg, int index)
> > > {
> > >    if (index >= 4)
> > >      {
> > >        warn ();
> > >        *ptr = 0;            // Code duplications since "warn" does
> return;
> > >        *val = sg->vals[index];      // same this line.
> > >                             // In this path, since it's under the
> condition
> > >                             // "index >= 4", the compiler knows the
> value
> > >                             // of "index" is larger then 4, therefore
> the
> > >                             // out-of-bound warning.
> > >        warn ();
> > >      }
> > >    else
> > >      {
> > >        *ptr = 0;
> > >        *val = sg->vals[index];
> > >      }
> > >    *ptr = *val;
> > >    return;
> > > }
> > >
> > > We can see, after the thread jump optimization, the # of branches
> inside
> > > the routine "sparx5_set" is reduced from 2 to 1, however,  due to the
> > > code duplication (which is needed for the correctness of the code), we
> > > got a false positive out-of-bound warning.
> > >
> > > In order to eliminate such false positive out-of-bound warning,
> > >
> > > A. Add one more flag for GIMPLE: is_splitted.
> > > B. During the thread jump optimization, when the basic blocks are
> > >     duplicated, mark all the STMTs inside the original and duplicated
> > >     basic blocks as "is_splitted";
> > > C. Inside the array bound checker, add the following new heuristic:
> > >
> > > If
> > >     1. the stmt is duplicated and splitted into two conditional paths;
> > > +  2. the warning level < 2;
> > > +  3. the current block is not dominating the exit block
> > > Then not report the warning.
> > >
> > > The false positive warnings are moved from -Warray-bounds=1 to
> > >   -Warray-bounds=2 now.
> > >
> > > Bootstrapped and regression tested on both x86 and aarch64. adjusted
> > >   -Warray-bounds-61.c due to the false positive warnings.
> > >
> > > Let me know if you have any comments and suggestions.
> > This sounds horribly wrong.   In the code above, the warning is correct.
>
> It's not sensible from a user's perspective.
>
> If this doesn't warn:
>
> void sparx5_set (int * ptr, struct nums * sg, int index)
> {
>    *ptr = 0;
>    *val = sg->vals[index];
>    *ptr = *val;
> }
>
> ... because the value range tracking of "index" spans [INT_MIN,INT_MAX],
> and warnings based on the value range are silenced if they haven't been
> clamped at all. (Otherwise warnings would be produced everywhere: only
> when a limited set of values is known is it useful to produce a warning.)
>
>
> But it makes no sense to warn about:
>
> void sparx5_set (int * ptr, struct nums * sg, int index)
> {
>    if (index >= 4)
>      warn ();
>    *ptr = 0;
>    *val = sg->vals[index];
>    if (index >= 4)
>      warn ();
>    *ptr = *val;
> }
>
> Because at "*val = sg->vals[index];" the actual value range tracking for
> index is _still_ [INT_MIN,INT_MAX]. (Only within the "then" side of the
> "if" statements is the range tracking [4,INT_MAX].)
>
> However, in the case where jump threading has split the execution flow
> and produced a copy of "*val = sg->vals[index];" where the value range
> tracking for "index" is now [4,INT_MAX], is the warning valid. But it
> is only for that instance. Reporting it for effectively both (there is
> only 1 source line for the array indexing) is misleading because there
> is nothing the user can do about it -- the compiler created the copy and
> then noticed it had a range it could apply to that array index.
>

"there is nothing the user can do about it" is very much false. They could
change warn call into a noreturn function call instead.  (In the case of
the Linux kernel panic). There are things the user can do to fix the
warning and even get better code generation out of the compilers.

Thanks,
Andrew



> This situation makes -Warray-bounds unusable for the Linux kernel (we
> cannot have false positives says BDFL), but we'd *really* like to have
> it enabled since it usually finds real bugs. But these false positives
> can't be fixed on our end. :( So, moving them to -Warray-bounds=2 makes
> sense as that's the level documented to have potential false positives.
>
> -Kees
>
> --
> Kees Cook
>

  reply	other threads:[~2024-05-13 23:39 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-13 19:48 Qing Zhao
2024-05-13 20:46 ` Jeff Law
2024-05-13 21:41   ` Kees Cook
2024-05-13 23:38     ` Andrew Pinski [this message]
2024-05-14  0:14       ` Kees Cook
2024-05-14 14:57         ` Qing Zhao
2024-05-14 15:08           ` Jeff Law
2024-05-14 16:03             ` Qing Zhao
2024-05-14 13:08 ` Richard Biener
2024-05-14 14:17   ` Qing Zhao
2024-05-14 14:29     ` Richard Biener
2024-05-14 15:19       ` Qing Zhao
2024-05-14 17:14         ` Richard Biener
2024-05-14 17:21           ` Qing Zhao
2024-05-15  6:09             ` Richard Biener
2024-05-15 13:37               ` Qing Zhao
2024-05-14 19:50     ` Kees Cook
2024-05-15  5:50       ` Richard Biener
2024-05-15 14:00   ` David Malcolm
2024-05-21 15:13     ` Qing Zhao
2024-05-21 21:36       ` David Malcolm
2024-05-22  7:38         ` Richard Biener
2024-05-22 18:53           ` Qing Zhao
2024-05-23 11:46             ` Richard Biener
2024-05-23 14:03               ` Qing Zhao
2024-05-23 14:13                 ` David Malcolm
2024-05-23 14:23                   ` Qing Zhao
2024-05-31 21:22               ` Qing Zhao
2024-06-03  6:29                 ` Richard Biener
2024-06-03 14:33                   ` Qing Zhao
2024-06-03 14:48                   ` David Malcolm
2024-06-04  7:43                     ` Richard Biener
2024-06-04 20:30                       ` Qing Zhao
2024-06-05  7:26                         ` Richard Biener
2024-06-05 16:38                           ` Qing Zhao
2024-06-05 17:07                             ` Richard Biener
2024-06-05 17:58                               ` Qing Zhao
2024-06-07 19:13                                 ` Qing Zhao
2024-06-12 18:15                                   ` Qing Zhao
2024-05-14 16:43 ` 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='CA+=Sn1mGaP5mH5y9HCjqgdbNdBeQBYtrJfnBagFCLyqioyKCpw@mail.gmail.com' \
    --to=pinskia@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jeffreyalaw@gmail.com \
    --cc=keescook@chromium.org \
    --cc=qing.zhao@oracle.com \
    --cc=rguenther@suse.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).