On Sun, Dec 14, 2014 at 08:14:18PM +0100, Adam Wolk wrote:

> Hi all,
> 
> Not that long ago we saw a lot of commits related to null checks being
> not needed before free() calls.
> 
> Here are some examples:
>  -
>  
> http://www.freshbsd.org/commit/openbsd/6abf83ab833f1b0161938ac26ce5a549fd4b7cef
> 
> > There is no point in checking if a pointer is non-NULL before calling free,
> > since free already does this for us. Also remove some pointless NULL
> > assignments, where the result from malloc(3) is immediately assigned to the
> > same variable.
> > 
> > ok miod@
> 
>  -
>  
> http://www.freshbsd.org/commit/openbsd/9064b3d5fe0973bd390119ca172f336b1fe1863a?diff=sys%2Fnet%2Fbpf.c
> 
> > some say you don't need NULL checks before free(). Not 0 either.
> 
>  -
>  
> http://www.freshbsd.org/commit/openbsd/c02cf11d29c35fab75ffd1c0d372ad7a23e9eb04
> 
> > no need for null check before free. from Brendan MacDonell
> 
>  -
>  
> http://www.freshbsd.org/commit/openbsd/8b32e1e5ac05d953ce3576b501af19ac6c2f48b2
> 
> > more: no need for null check before free
> > ok tedu guenther
> 
> -
> http://www.freshbsd.org/commit/openbsd/4e358956230836c457633798c48a836a7494629d
> 
> > more: no need to null check before free; ok guenther
> 
> Many more in this freshbsd search:
> http://www.freshbsd.org/search?committer=&branch=&project=openbsd&q=null+free
> 
> Now this came up in a discussion I had on IRC and wanted to point out
> the person asking the question to free(3) man page and was surprised to
> find this two passages:
> 
> > If ptr is a NULL pointer, no action occurs.  If ptr was previously freed by 
> > free()
> > realloc(), or reallocarray(), the behavior is undefined and the double
> > free is a security concern.
> 
> and
> 
> > ``bogus pointer (double free?)''
> >  An attempt to free(), realloc(), or reallocarray() an unallocated
> > pointer was made.
> 
> So how should I interpret this in relation to the above commit messages?
> 
>  1) double free is safe, no need for null checks
>  2) double free is detected by OpenBSD, no need for null checks we will
>  kill your program
>  3) double free is unsafe, avoid double free
> 
> I would like to think that (2) is true. Though reading the man page
> makes an initial impression (at least for me) that (3) is true and could
> lead to people following the rule of null checking before a free call?
> 
> Should the man page be altered to discouraged the use of null checks
> before calls to free?

You seem to be confused, a null pointer check cannot avoid a double
free in general.

As I see it, tHhre are three cases:

1. free(NULL). That one is a no-op and you can drop the call.

2. free(p) where p is unitialized. We detect many of these calls, but
cannot detect all, since p might happen to point to previously
malloc'ed memory. These are bugs that should be fixed in your program. 

2. free(p) where p was previously free'ed. We detect most of these.
But due to randomization and some performance concerns, we cannot
detect all cases. They are a bug that should be fixed. Often assigning
NULL to p after the free call will do, a potential free(p) call after
that will be a no-op. 

The commits removed some NULL pointer checks like:

        if (p)
                free(p);

and replaced them by
        
        free(p);

Also, some calls of the form:

        p = NULL;
        p = malloc(...);

where changed into

        p = malloc(...);


The commits were done to get rid of redundant code, not to fix double
free's. 

        -Otto

Reply via email to