From: David Malcolm <dmalcolm@redhat.com>
To: Florian Weimer <fweimer@redhat.com>,
Martin Sebor via Libc-alpha <libc-alpha@sourceware.org>
Cc: Martin Sebor <msebor@gmail.com>, Joseph Myers <joseph@codesourcery.com>
Subject: Re: [PATCH] add support for -Wmismatched-dealloc
Date: Tue, 19 Jan 2021 11:54:42 -0500 [thread overview]
Message-ID: <93b9dd73b2cac2b53c49dbe4f76d4f8645591328.camel@redhat.com> (raw)
In-Reply-To: <87sg76led0.fsf@oldenburg2.str.redhat.com>
On Tue, 2021-01-12 at 09:59 +0100, Florian Weimer wrote:
> * Martin Sebor via Libc-alpha:
>
> > > realpath only returns a pointer to the heap if RESOLVED is null,
> > > so
> > > the annotation is wrong here.
> > This is intentional. When realpath() returns the last argument
> > (when it's nonnull) passing the returned pointer to free will not
> > be diagnosed but passing it to some other deallocator not
> > associated
> > with the function will be. That means for example that passing
> > a pointer allocated by C++ operator new() to realpath() and then
> > deleting the pointer returned from the function as opposed to
> > the argument will trigger a false positive. I decided this was
> > an okay trade-off because unless the function allocates memory
> > I expect the returned pointer to be ignored (similarly to how
> > the pointer returned from memcpy is ignored). If you don't like
> > the odds I can remove the attribute from the function until we
> > have one that captures this conditional return value (I'd like
> > to add one in GCC 12).
>
> Maybe David can comment on how this interacts with his static
> analyzer
> work.
BTW, the -fanalyzer part of support for
__attribute__((malloc(deallocator))) is in gcc 11 as of yesterday:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=c7e276b869bdeb4a95735c1f037ee1a5f629de3d
> In all other cases, the attribute means that the pointer needs to
> be freed to avoid a resource leak.
Indeed, the analyzer doesn't have any special knowledge of realpath and
the conditional behavior. Given that annotation it will assume that
the returned value is either a pointer that needs to be freed, or NULL
on a failure, with no knowledge that the 2nd argument could be
returned.
I haven't tested Martin's patch, but I tried this example:
$ cat t.c
#include <stdio.h>
#define PATH_MAX 4096
void free(void *ptr);
char *realpath(const char *path, char *resolved_path)
__attribute__ ((malloc (free)))
__attribute__ ((__warn_unused_result__));
void test_1 (const char *path)
{
char buf[PATH_MAX];
char *result = realpath (path, buf);
printf ("result: %s\n", result);
}
void test_2 (const char *path)
{
char buf[PATH_MAX];
char *result = realpath (path, buf);
printf ("result: %s\n", result);
free (result);
}
I believe test_1 is correct (although redundant in its use of "result"
rather than buf, and can output a truncated path).
I believe test_2 is a crasher bug: a "free" of on-stack "buf".
Compiling with GCC 11 (with the __attribute__((malloc (DEALLOCATOR)))
support:
$ ./xgcc -B. -c -fanalyzer t.c
t.c: In function ‘test_1’:
t.c:14:1: warning: leak of ‘result’ [CWE-401] [-Wanalyzer-malloc-leak]
14 | }
| ^
‘test_1’: events 1-2
|
| 12 | char *result = realpath (path, buf);
| | ^~~~~~~~~~~~~~~~~~~~
| | |
| | (1) allocated here
| 13 | printf ("result: %s\n", result);
| 14 | }
| | ~
| | |
| | (2) ‘result’ leaks here; was allocated at (1)
|
Here it falsely complains about test_1; it doesn't "know" that buf is
returned by realpath and assumes that result needs to be freed.
In test_2, there's a free of result == buf i.e. a free of an on-stack
buffer, which it doesn't complain about, treating "result" as a malloc-
ed pointer (as specified by the attribute).
So I don't think this attribute should be applied to realpath.
If we suddenly apply it pointers
> which can only conditionally be freed, that reduces the value of
> those
> annotations, I think.
FWIW, the analyzer already special-cases some functions; see the
various region_model::impl_call_* functions in:
https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/analyzer/region-model-impl-calls.cc
There's a case for doing this for stuff in POSIX, which would apply
here, I think.
As noted above, I haven't tested Martin's glibc patch (I don't think
I'm subscribed to this list).
> Thanks,
> Florian
Hope this is constructive
Dave
next prev parent reply other threads:[~2021-01-19 16:54 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-08 22:52 Martin Sebor
2020-12-09 0:07 ` Joseph Myers
2020-12-12 2:25 ` Martin Sebor
2020-12-14 21:39 ` Martin Sebor
2020-12-14 22:16 ` Florian Weimer
2020-12-15 1:01 ` Joseph Myers
2020-12-15 16:52 ` Martin Sebor
2020-12-27 23:13 ` Martin Sebor
2021-01-04 15:56 ` Ping: " Martin Sebor
2021-01-04 16:07 ` Florian Weimer
2021-01-04 16:18 ` Martin Sebor
2021-01-04 16:57 ` Florian Weimer
2021-01-04 23:18 ` Martin Sebor
2021-01-10 20:42 ` Ping: " Martin Sebor
2021-01-11 9:13 ` Florian Weimer
2021-01-12 0:00 ` Martin Sebor
2021-01-12 0:01 ` Martin Sebor
2021-01-12 8:59 ` Florian Weimer
2021-01-19 1:08 ` Martin Sebor
2021-01-19 16:54 ` David Malcolm [this message]
2021-01-22 21:26 ` DJ Delorie
2021-01-25 10:56 ` Florian Weimer
2021-01-25 11:31 ` Florian Weimer
2021-04-23 0:00 ` Martin Sebor
2021-05-06 23:54 ` Martin Sebor
2021-05-13 21:49 ` Martin Sebor
2021-05-16 21:25 ` Martin Sebor
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=93b9dd73b2cac2b53c49dbe4f76d4f8645591328.camel@redhat.com \
--to=dmalcolm@redhat.com \
--cc=fweimer@redhat.com \
--cc=joseph@codesourcery.com \
--cc=libc-alpha@sourceware.org \
--cc=msebor@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 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).