Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Thu, 25 Feb 2021 14:02:25 -0800
From: David Goldblatt <davidtgoldblatt@...il.com>
To: Paul Eggert <eggert@...ucla.edu>
Cc: libc-coord@...ts.openwall.com
Subject: Re: Sized deallocation for C

On Thu, Feb 25, 2021 at 11:58 AM Paul Eggert <eggert@...ucla.edu> wrote:
>
> The draft text says:
>
> "If ptr is the result obtained from a call to malloc(size),
> realloc(old_ptr, size), or calloc(nmemb, memb_size), where nmemb *
> memb_size is equal to size, this function behaves equivalently to
> free(ptr)."
>
> Suppose my code does the following but nmemb * memb_size overflows and
> does not fit into size_t:
>
>   void
>   sample (size_t nmemb, size_t memb_size)
>   {
>     void *ptr = calloc (nmemb, memb_size);
>     if (ptr != NULL)
>       do_something_with (ptr);
>     free_sized (ptr, nmemb * memb_size);
>   }
>
> It's not clear from the wording whether behavior would be defined here,
> in the typical case where size_t is at least as width as int so the
> overflow wraps around in a well-defined way. Presumably the intent is
> that behavior should be defined. (Admittedly this is a weird corner
> case, but corner cases are what standards are for....
>
> A simple fix for this problem would be to change the above-quoted text
> to this:
>
> "If ptr is a null pointer, or is the result obtained from a call to
> malloc(size), realloc(old_ptr, size), or calloc(nmemb, memb_size) where
> size is the mathematical product of nmemb and size, this function
> behaves equivalently to free(ptr)."
>
> and similarly for free_aligned_sized. Plus, we add a requirement to
> calloc that it must return NULL if nmemb * memb_size does not fit into
> size_t.

I'll add a question in the design section for this. I think this may
already be readable as a requirement, since C object sizes must fit
into size_ts, but I can't pretend I'm an expert at this part of the
object model. But practically, "calloc returns NULL on overflow" is
important for a whole bunch of reasons, so we should just say it does
what every implementation actually does.

> Alternatively there could be a different 'free' function for calloc, but
> this proposal already has too many 'free' functions.
>
> PS. Come to think of it, we could easily get by with one new 'free'
> function instead of two, as free_aligned_sized (ptr, 0, size) could take
> on the role of free_sized(ptr, size). I'd prefer this simplification.

On the other hand, this introduces a tighter coordination between
argument parameters and allocation sources (e.g. the static
information of "allocation source" would determine the dynamic
argument parameter). It also sort of hurts the C-as-substrate folks,
who now take an extra branch within the allocator. I'll add a design
question section for this as well.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.