malloc: port to current -m32 AddressSanitizer

Also, port better to non-glibc, and in documentation update the
list of platforms needing a fix.  This includes 32-bit platforms
using AddressSanitizer, unfortunately.
* m4/malloc.m4 (gl_CHECK_MALLOC_PTRDIFF): Invoke gl_MUSL_LIBC.
musl is safe, as is FreeBSD 11+, NetBSD 8+, OpenBSD 5.6+, AIX,
Microsoft Windows.  However, the AddressSanitizer is unsafe.
This commit is contained in:
Paul Eggert
2026-07-27 15:09:35 -07:00
parent fc686d171c
commit 6f013454d4
6 changed files with 61 additions and 13 deletions
+10
View File
@@ -1,3 +1,13 @@
2026-07-27 Paul Eggert <eggert@cs.ucla.edu>
malloc: port to current -m32 AddressSanitizer
Also, port better to non-glibc, and in documentation update the
list of platforms needing a fix. This includes 32-bit platforms
using AddressSanitizer, unfortunately.
* m4/malloc.m4 (gl_CHECK_MALLOC_PTRDIFF): Invoke gl_MUSL_LIBC.
musl is safe, as is FreeBSD 11+, NetBSD 8+, OpenBSD 5.6+, AIX,
Microsoft Windows. However, the AddressSanitizer is unsafe.
2026-07-26 Bruno Haible <bruno@clisp.org>
[v]szprintf: Improve port to Fil-C.
+6 -2
View File
@@ -21,9 +21,13 @@ which also conforms to POSIX and is GNU-compatible:
Solaris 11.4.
@item
On some platforms, @code{calloc (n, s)} can succeed even if
On some 32-bit platforms, @code{calloc (n, s)} can succeed even if
multiplying @code{n} by @code{s} would exceed @code{PTRDIFF_MAX} or
@code{SIZE_MAX}. Although failing to check for exceeding
@code{SIZE_MAX}, which can lead to undefined behavior later:
AddressSanitizer of gcc 16.1 or clang 22.1, glibc 2.29, FreeBSD 10.4,
NetBSD 7.2, OpenBSD 5.5, macOS 10.14, AIX 7.3, Solaris 11.4.
Although failing to check for exceeding
@code{PTRDIFF_MAX} is arguably allowed by POSIX it can lead to
undefined behavior later, so @code{calloc-posix} does not allow
going over the limit.
+6 -2
View File
@@ -21,8 +21,12 @@ which also conforms to POSIX and is GNU-compatible:
Solaris 11.4.
@item
On some platforms, @code{malloc (n)} can succeed even if @code{n}
exceeds @code{PTRDIFF_MAX}. Although this behavior is arguably
On some 32-bit platforms, @code{malloc (n)} can succeed even if @code{n}
exceeds @code{PTRDIFF_MAX}, which can lead to undefined behavior later:
AddressSanitizer of gcc 16.1 or clang 22.1, glibc 2.29, FreeBSD 10.4,
NetBSD 7.2, OpenBSD 5.5, macOS 10.14, AIX 7.3, Solaris 11.4.
Although this behavior is arguably
allowed by POSIX it can lead to behavior not defined by POSIX later,
so @code{malloc-posix} does not allow going over the limit.
@end itemize
+6 -2
View File
@@ -23,8 +23,12 @@ which also conforms to POSIX and is GNU-compatible:
Solaris 11.4.
@item
On some platforms, @code{realloc (p, n)} can succeed even if @code{n}
exceeds @code{PTRDIFF_MAX}. Although this behavior is arguably
On some 32-bit platforms, @code{realloc (p, n)} can succeed even if @code{n}
exceeds @code{PTRDIFF_MAX}, which can lead to undefined behavior later:
AddressSanitizer of gcc 16.1 or clang 22.1, glibc 2.29, FreeBSD 10.4,
NetBSD 7.2, OpenBSD 5.5, macOS 10.14, AIX 7.3, Solaris 11.4.
Although this behavior is arguably
allowed by POSIX it is not compatible with GNU and
can lead to behavior not defined by POSIX later,
so @code{realloc-posix} does not allow going over the limit.
+7 -2
View File
@@ -34,10 +34,15 @@ which also conforms to POSIX and is GNU-compatible:
Solaris 11.4.
@item
On some platforms, @code{reallocarray (p, n, s)} can succeed even if
On some 32-bit platforms, @code{reallocarray (p, n, s)} can succeed even if
multiplying @code{n} by @code{s} would exceed @code{PTRDIFF_MAX},
which can lead to undefined behavior later:
FreeBSD 13, NetBSD 9, OpenBSD 6, musl 1.2.
AddressSanitizer of gcc 16.1 or clang 22.1, glibc 2.29, Solaris 11.4.
Although this behavior is arguably
allowed by POSIX it is not compatible with GNU and
can lead to behavior not defined by POSIX later,
so @code{realloc-posix} does not allow going over the limit.
@item
It is not portable to call
+26 -5
View File
@@ -1,5 +1,5 @@
# malloc.m4
# serial 46
# serial 47
dnl Copyright (C) 2007, 2009-2026 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -104,6 +104,7 @@ AC_DEFUN([gl_FUNC_MALLOC_PTRDIFF],
# Set gl_cv_func_malloc_gnu.
AC_DEFUN([gl_CHECK_MALLOC_PTRDIFF],
[
gl_MUSL_LIBC
AC_CACHE_CHECK([whether malloc is ptrdiff_t safe],
[gl_cv_malloc_ptrdiff],
[AC_COMPILE_IFELSE(
@@ -118,10 +119,30 @@ AC_DEFUN([gl_CHECK_MALLOC_PTRDIFF],
is no problem. */
#define NARROW_SIZE (SIZE_MAX <= PTRDIFF_MAX)
/* glibc 2.30 and later malloc refuses to exceed ptrdiff_t
bounds even on 32-bit platforms. We don't know which
non-glibc systems are safe. */
#define KNOWN_SAFE (2 < __GLIBC__ + (30 <= __GLIBC_MINOR__))
/* Whether address sanitization is in use.
clang 4 through 21 signal this only with __has_feature. */
#if !defined __SANITIZE_ADDRESS__ && defined __has_feature
# if __has_feature (address_sanitizer)
# define __SANITIZE_ADDRESS__ 1
# endif
#endif
#if __OpenBSD__ || __NetBSD__
#include <sys/param.h>
#endif
/* Many platforms are safe: malloc stays in ptrdiff_t bounds.
However, with address sanitization, gcc (up to at least
gcc 16.1) and clang (up to at least clang 22) interpose
a malloc that can go over a 32-bit ptrdiff_t limit. See:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126436
https://github.com/llvm/llvm-project/issues/212288
If we don't know a platform is safe, assume it's unsafe. */
#define KNOWN_SAFE \
(((2 < __GLIBC__ + (30 <= __GLIBC_MINOR__)) || MUSL_LIBC \
|| 11 <= __FreeBSD__ || 800000000 <= __NetBSD_Version__ \
|| 201411 <= OpenBSD || defined _WIN32) \
&& !__SANITIZE_ADDRESS__)
#if WIDE_PTRDIFF || NARROW_SIZE || KNOWN_SAFE
return 0;