![]() |
|
Message-ID: <bycgdwyfvwmmo5qvisxnpefnesbhsq2nk6v3fb7c6kzufbyulk@hefcxeyewepn>
Date: Tue, 17 Jun 2025 01:20:11 +0200
From: Alejandro Colomar <alx@...nel.org>
To: Florian Weimer <fweimer@...hat.com>
Cc: Adhemerval Zanella Netto <adhemerval.zanella@...aro.org>,
musl@...ts.openwall.com, libc-alpha@...rceware.org, Joseph Myers <josmyers@...hat.com>,
наб <nabijaczleweli@...ijaczleweli.xyz>, Paul Eggert <eggert@...ucla.edu>,
Robert Seacord <rcseacord@...il.com>, Elliott Hughes <enh@...gle.com>, Bruno Haible <bruno@...sp.org>,
bug-gnulib@....org, JeanHeyd Meneide <phdofthehouse@...il.com>,
Douglas McIlroy <douglas.mcilroy@...tmouth.edu>, Rich Felker <dalias@...c.org>,
Florian Weimer <fweimer@...hat.com>, Wilco Dijkstra <Wilco.Dijkstra@....com>,
DJ Delorie <dj@...hat.com>, Siddhesh Poyarekar <siddhesh@...plt.org>,
Sam James <sam@...too.org>
Subject: Re: BUG: realloc(p,0) should be consistent with malloc(0)
On Mon, Jun 16, 2025 at 11:44:53PM +0200, Alejandro Colomar wrote:
> How about I write a proposal to the committee, in which I talk about the
> current situation, and how glibc and Bionic are the only broken
> implementation, and propose a change to ISO C which blesses the behavior
> of all other implementations, rendering glibc and Bionic non-conforming?
> I can then propose a very explicit question:
>
> If glibc and Bionic agreed to change their behavior according to
> this proposal, would the C Committee agree to this change?
>
> And then come back to glibc with that. If I get such a conditional
> approval of such a proposal, would glibc then apply the fix?
Hi all,
Here's a draft of a proposal. Please let me know: if the C Committee
voted yes to the question in this proposal, would glibc change behavior?
See the proposal below.
Have a lovely night!
Alex
---
Name
alx-0029r0 - realloc(p,0) should be consistent with malloc(0)
Principles
- Codify existing practice to address evident deficiencies.
- Enable secure programming
Category
Remove UB
Author
Alejandro Colomar <alx@...nel.org>
Cc: наб <nabijaczleweli@...ijaczleweli.xyz>
Cc: Douglas McIlroy <douglas.mcilroy@...tmouth.edu>
Cc: Paul Eggert <eggert@...ucla.edu>
Cc: Bruno Haible <bruno@...sp.org>
Cc: Robert Seacord <rcseacord@...il.com>
Cc: JeanHeyd Meneide <phdofthehouse@...il.com>
Cc: Elliott Hughes <enh@...gle.com>
Cc: Rich Felker <dalias@...c.org>
Cc: Adhemerval Zanella Netto <adhemerval.zanella@...aro.org>
Cc: Joseph Myers <josmyers@...hat.com>
Cc: Florian Weimer <fweimer@...hat.com>
Cc: Wilco Dijkstra <Wilco.Dijkstra@....com>
Cc: DJ Delorie <dj@...hat.com>
Cc: Siddhesh Poyarekar <siddhesh@...plt.org>
Cc: Sam James <sam@...too.org>
History
<https://www.alejandro-colomar.es/src/alx/alx/wg14/alx-0029.git/>
r0 (2025-06-17):
- Initial draft.
See also
<https://nabijaczleweli.xyz/content/blogn_t/017-malloc0.html>
<https://inbox.sourceware.org/libc-alpha/nbyurzcgzgd5rdybbi4no2kw5grrc32k63svf7oq73nfcbus5r@77gry66kpqfr/>
<https://inbox.sourceware.org/libc-alpha/qukfe5yxycbl5v7ooskvqdnm3au3orohbx4babfltegi47iyly@or6dgf7akeqv/>
Description
Most libc implementations have realloc(p,0) be consistent with
malloc(0). If their malloc(0) returns nonnull, realloc(p,0)
also returns nonnull. If their malloc(0) returns a null
pointer, realloc(p,0) also returns a null pointer.
That consistency was present in the old UNIX V7, where
realloc(3) was first introduced, and it has been consistent in
all the descendents of the UNIX system.
The original malloc(0) in UNIX v7 returned non-null. UNIX v6
had alloc(3), which was the precursor of V7's malloc(3), and it
also returned non-null. The BSD line kept this behavior, while
SysV eventually moved to returning a null pointer, in what seems
a documentation bug that eventually degenerated into the actual
behavior.
Regardless of the result of malloc(0) in the descendents of the
UNIX system, they all maintained a congruency between malloc(0)
and realloc(p,0).
Until the ISO C and POSIX standards were badly written, and also
badly rewritten, and they allowed behaviors that didn't make any
sense, and which didn't derive from any existing implementation.
Then, glibc was written by following the letter of the standard,
instead of trying to follow what other systems do. And this
resulted in a self-inconsistent implementation, whose malloc(0)
returns non-null, but whose realloc(p,0) returns a null pointer.
Bionic libc followed glibc, and has the same self-inconsistent
behavior.
There are no other known libc implementations whose realloc(p,0)
isn't consistent with malloc(0). Even musl libc, which coexists
in Linux systems with glibc, has a realloc(p,0) which is
consistent with malloc(0) and returns non-null.
There are glibc maintainers that agree with fixing glibc to be
self-consistent, but a few of them are worried that the
C Committee might standardize in a different way, so they are
reticent to fix their implementation if the C Committee doesn't
agree on a direction.
At the same time, the C Committee refuses standardization of
realloc(p,0) due to existing implementations being inconsistent
in dangerous ways.
Prior art
gnulib has a module realloc-posix, whose behavior was like the
one in glibc. After realizing how bad this behavior was, gnulib
has changed to be consistent with malloc(), and thus return
non-null. This was done in commit
gnulib.git d884e6fc4a60 (2024-11-03, 2024-11-04; "realloc-posix: realloc (..., 0) now returns nonnull")
After more than half a year since that, no regressions have been
reported. As expected, there was no fallout at all from this
change.
Questions to the committee
Does the C Committee agree on a change along the lines of the
proposed wording in this proposal, conditional to glibc and
Bionic libc fixing their implementations in this direction
first?
Future directions
malloc(0) returning a null pointer on success originated as a
documentation bug in SysV, and later became the actual behavior.
It was standardized in C89 maybe because early SVID
specifications documented that, or maybe simply because C89 had
this idea that 0-sized objects cannot exist. Regardless of the
rationale, it results in malloc(0) being hard to use correctly
on those systems. Fixing malloc(0) to return non-null would
result in many bugs fixed, and probably no regressions. I plan
to propose mandating malloc(0) to return non-null, as any other
malloc() call.
realloc(p,0) will then also return non-null, as the wording
below defines it as if it called malloc().
Proposed wording
Based on N3550.
7.25.4.8 Memory management functions :: The realloc function
@@ Description
+On success,
+the realloc function
behaves like <tt>free(ptr); malloc(size)</tt>.
deallocates the old object pointed to by ptr
+as if by a call to <b>free</b>,
and returns a pointer to a new object
-that has the size specified by size.
-that has the size specified by size
+as if by a call to <b>malloc</b>.
The contents of the new object
shall be the same as that of the old object prior to deallocation,
up to the lesser of the new and old sizes.
Any bytes in the new object beyond the size of the old object
have unspecified values.
## The following sentence seems redundant with the specification
## above.
-If ptr is a null pointer,
-the realloc function behaves
-like the malloc function for the specified size.
-Otherwise,
-if <tt>ptr</tt> does not match
+If <tt>ptr</tt> does not match
a pointer earlier returned by a memory management function,
or if the space has been deallocated
by a call to the free or realloc function,
-or if the size is zero,
the behavior is undefined.
-If memory for the new object is not allocated,
+If allocation of the new object fails,
the old object is not deallocated and its value is unchanged.
--
<https://www.alejandro-colomar.es/>
Download attachment "signature.asc" of type "application/pgp-signature" (834 bytes)
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.