git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Phillip Wood <phillip.wood123@gmail.com>
To: "René Scharfe" <l.s.r@web.de>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Cc: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>,
	Jinoh Kang <luke1337@theori.io>, Glen Choo <chooglen@google.com>,
	Paul Tan <pyokagan@gmail.com>,
	Han-Wen Nienhuys <hanwen@google.com>,
	Karthik Nayak <karthik.188@gmail.com>,
	Jeff Smith <whydoubt@gmail.com>, Taylor Blau <me@ttaylorr.com>
Subject: Re: [RFC PATCH 07/15] strbuf.c: placate -fanalyzer in strbuf_grow()
Date: Sun, 5 Jun 2022 11:20:37 +0100	[thread overview]
Message-ID: <bcbdd8db-763e-b910-3fe7-a5f11d3ff39b@gmail.com> (raw)
In-Reply-To: <8a5cdd7a-13bf-b091-e947-657aeb094c38@web.de>

On 04/06/2022 21:37, René Scharfe wrote:
> Am 04.06.22 um 18:21 schrieb Ævar Arnfjörð Bjarmason:
>>
>> On Sat, Jun 04 2022, Phillip Wood wrote:
>>
>>> Hi Ævar
>>>
>>> [This is an old address that I only have webmail access to, please use
>>> phillip.wood@dunelm.org.uk when cc'ing me]
>>
>> Hrm, I just grabbed it from an old commit of yours I found. Consider
>> sending in a patch to update .mailmap :)
>>
>>>> On 03 June 2022 at 19:37 Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
>>>>
>>>>
>>>> Change the strbuf_grow() function so that GCC v12's -fanalyze doesn't
>>>> yell at us about sb->buf[0] dereferencing NULL, this also makes this
>>>> code easier to follow.
>>>>
>>>> This BUG() should be unreachable since the state of our "sb->buf" and
>>>> "sb->alloc" goes hand-in-hand, but -fanalyzer isn't smart enough to
>>>> know that, and adding the BUG() also makes it clearer to human readers
>>>> that that's what happens here.
>>>>
>>>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>>>> ---
>>>>   strbuf.c | 2 ++
>>>>   1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/strbuf.c b/strbuf.c
>>>> index dd9eb85527a..61c4630aeeb 100644
>>>> --- a/strbuf.c
>>>> +++ b/strbuf.c
>>>> @@ -97,6 +97,8 @@ void strbuf_grow(struct strbuf *sb, size_t extra)
>>>>   	if (new_buf)
>>>>   		sb->buf = NULL;
>>>>   	ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
>>>> +	if (new_buf && !sb->buf)
>>>> +		BUG("for a new buffer ALLOC_GROW() should always do work!");
>>>
>>> This is a bit ugly, have you tried adding
>>> __attribute__((malloc (free), returns_nonnull))
>>> to xmalloc() and xrealloc() ?
>>>
>>
>> Will try to experiment with that, perhaps GCC can be massaged to grok
>> this somehow.
>>
>> I do vaguely remember (but couldn't track down where it was) that we
>> have some config for coverity for this function, due to it also having
>> trouble with it.
> 
> Good idea, but this attribute doesn't seem to help here.

Indeed, I was tricked by the misleading BUG message, the analyzer is not 
complaining that xrealloc() may return NULL, it is taking a path where 
it does not reallocate the buffer. I've copied the full output at the 
end of the message if anyone wants to see the whole thing but the 
relevant part is

            |cache.h:727:20:
            |  727 |                 if ((nr) > alloc) { \
            |      |                    ^
            |      |                    |
            |      |                    (10) following ‘false’ branch...
strbuf.c:99:9: note: in expansion of macro ‘ALLOC_GROW’
            |   99 |         ALLOC_GROW(sb->buf, sb->len + extra + 1, 
sb->alloc);
            |      |         ^~~~~~~~~~

> The following helps, but I don't know why it would be needed -- if alloc
> is 0 then any strbuf_grow() call will give a nr of at least 1 (for the
> NUL character):

Yes it seems to be ignoring the result of our overflow checks and 
assuming that sb->len + extra + 1 can overflow to zero. Having seen the 
number of false positives I'm inclined to think we should take the bug 
fixes and punt the rest of these patches. Maybe after a couple more gcc 
releases the false positive rate will be more manageable. (I tired 
running gcc 11 with -fanalyzer a few months ago and gave up looking at 
the output before I found a single real bug so it has certainly improved 
in gcc 12)

Best Wishes

Phillip

strbuf.c: In function ‘strbuf_grow’:
strbuf.c:101:28: warning: dereference of NULL ‘0’ [CWE-476] 
[-Wanalyzer-null-dereference]
   101 |                 sb->buf[0] = '\0';
       |                 ~~~~~~~~~~~^~~~~~
   ‘strbuf_normalize_path’: events 1-2
     |
     | 1156 | int strbuf_normalize_path(struct strbuf *src)
     |      |     ^~~~~~~~~~~~~~~~~~~~~
     |      |     |
     |      |     (1) entry to ‘strbuf_normalize_path’
     |......
     | 1160 |         strbuf_grow(&dst, src->len);
     |      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~
     |      |         |
     |      |         (2) calling ‘strbuf_grow’ from ‘strbuf_normalize_path’
     |
     +--> ‘strbuf_grow’: events 3-4
            |
            |   91 | void strbuf_grow(struct strbuf *sb, size_t extra)
            |      |      ^~~~~~~~~~~
            |      |      |
            |      |      (3) entry to ‘strbuf_grow’
            |......
            |   94 |         if (unsigned_add_overflows(extra, 1) ||
            |      |            ~
            |      |            |
            |      |            (4) following ‘false’ branch (when 
‘extra != 18446744073709551615’)...
            |
          ‘strbuf_grow’: event 5
            |
            |   95 |             unsigned_add_overflows(sb->len, extra + 1))
git-compat-util.h:128:7: note: in definition of macro 
‘unsigned_add_overflows’
            |  128 |     ((b) > maximum_unsigned_value_of_type(a) - (a))
            |      |       ^
            |
          ‘strbuf_grow’: events 6-9
            |
            |strbuf.c:94:46:
            |   94 |         if (unsigned_add_overflows(extra, 1) ||
            |......
            |   97 |         if (new_buf)
            |      |         ~~ ~
            |      |         |  |
            |      |         |  (8) following ‘true’ branch...
            |      |         (7) ...to here
            |   98 |                 sb->buf = NULL;
            |      |                 ~~
            |      |                 |
            |      |                 (9) ...to here
            |
          ‘strbuf_grow’: event 10
            |
            |cache.h:727:20:
            |  727 |                 if ((nr) > alloc) { \
            |      |                    ^
            |      |                    |
            |      |                    (10) following ‘false’ branch...
strbuf.c:99:9: note: in expansion of macro ‘ALLOC_GROW’
            |   99 |         ALLOC_GROW(sb->buf, sb->len + extra + 1, 
sb->alloc);
            |      |         ^~~~~~~~~~
            |
          ‘strbuf_grow’: event 11
            |
            |cache.h:726:12:
            |  726 |         do { \
            |      |            ^
            |      |            |
            |      |            (11) ...to here
strbuf.c:99:9: note: in expansion of macro ‘ALLOC_GROW’
            |   99 |         ALLOC_GROW(sb->buf, sb->len + extra + 1, 
sb->alloc);
            |      |         ^~~~~~~~~~
            |
          ‘strbuf_grow’: events 12-15
            |
            |  100 |         if (new_buf)
            |      |            ^
            |      |            |
            |      |            (12) following ‘true’ branch...
            |  101 |                 sb->buf[0] = '\0';
            |      |                 ~~~~~~~~~~~~~~~~~
            |      |                 | |        |
            |      |                 | |        (15) dereference of NULL 
‘*sb.buf’
            |      |                 | (14) ‘dst.buf’ is NULL
            |      |                 (13) ...to here


  reply	other threads:[~2022-06-05 10:20 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-03 18:37 [RFC PATCH 00/15] Fix GCC -fanalyzer warnings & add -fanalyzer DEVOPTS mode Ævar Arnfjörð Bjarmason
2022-06-03 18:37 ` [RFC PATCH 01/15] remote.c: don't dereference NULL in freeing loop Ævar Arnfjörð Bjarmason
2022-06-03 21:07   ` René Scharfe
2022-06-03 21:28     ` Junio C Hamano
2022-06-03 22:32     ` Glen Choo
2022-06-04 12:51     ` Phillip Wood
2022-06-04 16:20       ` Ævar Arnfjörð Bjarmason
2022-06-03 18:37 ` [RFC PATCH 02/15] pull.c: don't feed NULL to strcmp() on get_rebase_fork_point() path Ævar Arnfjörð Bjarmason
2022-06-03 21:27   ` René Scharfe
2022-06-03 18:37 ` [RFC PATCH 03/15] reftable: don't memset() a NULL from failed malloc() Ævar Arnfjörð Bjarmason
2022-06-03 22:22   ` René Scharfe
2022-06-04  0:54     ` Ævar Arnfjörð Bjarmason
2022-06-04 12:24       ` René Scharfe
2022-06-04 16:23         ` Ævar Arnfjörð Bjarmason
2022-06-04 20:31           ` René Scharfe
2022-06-06 16:53           ` Junio C Hamano
2022-06-06 17:38             ` Ævar Arnfjörð Bjarmason
2022-06-06 17:44               ` Junio C Hamano
2022-06-06 17:46                 ` Ævar Arnfjörð Bjarmason
2022-06-03 18:37 ` [RFC PATCH 04/15] diff-lib.c: don't dereference NULL in oneway_diff() Ævar Arnfjörð Bjarmason
2022-06-03 22:48   ` René Scharfe
2022-06-03 18:37 ` [RFC PATCH 05/15] refs/packed-backend.c: add a BUG() if iter is NULL Ævar Arnfjörð Bjarmason
2022-06-03 23:14   ` René Scharfe
2022-06-03 18:37 ` [RFC PATCH 06/15] ref-filter.c: BUG() out on show_ref() with NULL refname Ævar Arnfjörð Bjarmason
2022-06-04 18:07   ` René Scharfe
2022-06-03 18:37 ` [RFC PATCH 07/15] strbuf.c: placate -fanalyzer in strbuf_grow() Ævar Arnfjörð Bjarmason
2022-06-04 12:24   ` René Scharfe
2022-06-04 12:46   ` Phillip Wood
2022-06-04 16:21     ` Ævar Arnfjörð Bjarmason
2022-06-04 20:37       ` René Scharfe
2022-06-05 10:20         ` Phillip Wood [this message]
2022-06-03 18:37 ` [RFC PATCH 08/15] strbuf.c: use st_add3(), not unsigned_add_overflows() Ævar Arnfjörð Bjarmason
2022-06-04 21:27   ` René Scharfe
2022-06-03 18:37 ` [RFC PATCH 09/15] add-patch: assert parse_diff() expectations with BUG() Ævar Arnfjörð Bjarmason
2022-06-04 13:04   ` Phillip Wood
2022-06-03 18:37 ` [RFC PATCH 10/15] reftable: don't have reader_get_block() confuse -fanalyzer Ævar Arnfjörð Bjarmason
2022-06-03 18:37 ` [RFC PATCH 11/15] blame.c: clarify the state of "final_commit" for -fanalyzer Ævar Arnfjörð Bjarmason
2022-06-03 18:37 ` [RFC PATCH 12/15] pack.h: wrap write_*file*() functions Ævar Arnfjörð Bjarmason
2022-06-03 18:37 ` [RFC PATCH 13/15] pack-write API: pass down "verify" not arbitrary flags Ævar Arnfjörð Bjarmason
2022-06-03 18:37 ` [RFC PATCH 14/15] config.mak.dev: add a DEVOPTS=analyzer mode to use GCC's -fanalyzer Ævar Arnfjörð Bjarmason
2022-06-03 18:37 ` [RFC PATCH 15/15] config.mak.dev: add and use ASSERT_FOR_FANALYZER() macro Ævar Arnfjörð Bjarmason
2022-06-04 13:12   ` Phillip Wood
2022-06-07 15:50 ` [PATCH 0/3] remote API: fix -fanalyzer-spotted freeing issue Ævar Arnfjörð Bjarmason
2022-06-07 15:50   ` [PATCH 1/3] remote.c: remove braces from one-statement "for"-loops Ævar Arnfjörð Bjarmason
2022-06-07 15:50   ` [PATCH 2/3] remote.c: don't dereference NULL in freeing loop Ævar Arnfjörð Bjarmason
2022-06-07 17:23     ` Junio C Hamano
2022-06-07 15:50   ` [PATCH 3/3] remote API: don't buggily FREE_AND_NULL(), free() instead Ævar Arnfjörð Bjarmason
2022-06-07 17:02     ` Glen Choo
2022-06-07 18:09       ` Junio C Hamano
2022-06-07 17:29     ` Junio C Hamano
2022-06-07 17:32   ` [PATCH 0/3] remote API: fix -fanalyzer-spotted freeing issue Junio C Hamano

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bcbdd8db-763e-b910-3fe7-a5f11d3ff39b@gmail.com \
    --to=phillip.wood123@gmail.com \
    --cc=avarab@gmail.com \
    --cc=chooglen@google.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=hanwen@google.com \
    --cc=karthik.188@gmail.com \
    --cc=l.s.r@web.de \
    --cc=luke1337@theori.io \
    --cc=me@ttaylorr.com \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=pyokagan@gmail.com \
    --cc=whydoubt@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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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).