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 <a...@kernel.org> Cc: наб <nabijaczlew...@nabijaczleweli.xyz> Cc: Douglas McIlroy <douglas.mcil...@dartmouth.edu> Cc: Paul Eggert <egg...@cs.ucla.edu> Cc: Bruno Haible <br...@clisp.org> Cc: Robert Seacord <rcseac...@gmail.com> Cc: JeanHeyd Meneide <phdoftheho...@gmail.com> Cc: Elliott Hughes <e...@google.com> Cc: Rich Felker <dal...@libc.org> Cc: Adhemerval Zanella Netto <adhemerval.zane...@linaro.org> Cc: Joseph Myers <josmy...@redhat.com> Cc: Florian Weimer <fwei...@redhat.com> Cc: Wilco Dijkstra <wilco.dijks...@arm.com> Cc: DJ Delorie <d...@redhat.com> Cc: Siddhesh Poyarekar <siddh...@gotplt.org> Cc: Sam James <s...@gentoo.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/>
signature.asc
Description: PGP signature