2012.12.12 23:42 "[Tiff] Dealing with unportability of malloc(0)", by Tom Lane

2012.12.13 00:46 "Re: [Tiff] Dealing with unportability of malloc(0)", by Tom Lane

I noticed that Bob Friesenhahn recently committed this change to make _TIFFmalloc() behave the same on platforms where malloc(0) returns a zero-sized chunk of memory as it does on platforms where the same call returns NULL:

As far as I am aware, the malloc() on most systems returns NULL for a size of zero. We could create a test to confirm this if necessary.

Actually, that's the minority position. A quick check shows that Linux (glibc), Mac OS X, and HP-UX all return a nonnull value for malloc(0) --- that's the only Unix-oid platforms I have handy to check. So I suspect it's more likely that people will have only tested on platforms that behave this way than the other.

#include <stdio.h>
#include <stdlib.h>

int main()
{
        printf("%p\n", malloc(0));
        return 0;
}

If there's any possibility that some_request is (validly) zero, this code is now broken, because it will throw errors when it should not.

Can you think of such valid cases?

This same issue came up just recently in Postgres, which is where I spend most of my time. We had some code in a key program that did

        arrayptr = malloc(number-of-objects * sizeof(whatever))

where number-of-objects could legitimately be zero. This worked for a long time until somebody decided (reasonably) that it should have a test for malloc failure, rather than just dumping core with a null pointer dereference if that were to happen. So in went

        if (arrayptr == NULL)
                // fail

That kept working, and even made it to release, and it wasn't till our AIX users started complaining that we realized we'd made the behavior non-portable. So I have fairly fresh scars supporting my position that this is bad, as well as substantial evidence that most modern platforms don't return NULL.

The key question for libtiff of course is how often it might be important to cope with zero-length arrays. I'm not sure whether the TIFF spec forbids images of height or width zero, for instance, but libtiff has a problem with them.

None of this is terribly hard to fix, but first we need a policy decision about which platform-specific behavior we want to standardize on. I gave my argument above, does anyone want to advocate for the other way? Are there pieces of libtiff where the null-for-zero convention is preferable?

One reason why I like an argument of zero to produce NULL is that often there is a chunk of complex code which computes the size to allocate. In order to assure security, this complex code also needs to detect overflow conditions. Regardless, the decision then needs to be made how to report the overflow condition. A simple approach I have used in the past is to arrange to pass zero to the memory allocation function since there was always already error handling for memory allocation failure. This allows one error reporting path to handle both types of errors.

Yeah, I've noticed that a lot of the size-calculation functions in libtiff use a convention that zero return means overflow. That's fine as long as you're sure empty arrays can never be a legitimate case... but I think that's an assumption that will rise up to bite you eventually.

The long and the short of it is that we may be up against having to look at every single malloc call site if we want to be safe, whichever way we jump.

                        regards, tom lane