aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makeconfig14
-rw-r--r--Makerules2
-rwxr-xr-xconfigure40
-rw-r--r--configure.ac12
-rw-r--r--debug/Makefile13
-rw-r--r--debug/Versions3
-rw-r--r--debug/inet_ntop_chk.c30
-rw-r--r--debug/readonly-area.c23
-rw-r--r--debug/tst-fortify.c21
-rw-r--r--debug/tst-sprintf-fortify-rdonly-dlopen.c1
-rw-r--r--debug/tst-sprintf-fortify-rdonly-mod.c56
-rw-r--r--debug/tst-sprintf-fortify-rdonly.c158
-rw-r--r--elf/Makefile6
-rw-r--r--elf/chroot_canon.c5
-rw-r--r--elf/dl-readonly-area.c86
-rw-r--r--elf/rtld.c1
-rw-r--r--hurd/lookup-retry.c6
-rw-r--r--include/arpa/inet.h6
-rw-r--r--include/bits/inet-fortified-decl.h1
-rw-r--r--include/bits/inet-fortified.h1
-rw-r--r--include/stdlib.h15
-rw-r--r--inet/Makefile2
-rw-r--r--inet/arpa/inet.h5
-rw-r--r--inet/bits/inet-fortified-decl.h35
-rw-r--r--inet/bits/inet-fortified.h41
-rw-r--r--malloc/malloc.c2
-rw-r--r--manual/maint.texi2
-rw-r--r--stdio-common/vfprintf-internal.c9
-rw-r--r--stdio-common/vfprintf-process-arg.c28
-rw-r--r--stdlib/canonicalize.c6
-rw-r--r--stdlib/tst-canon-bz26341.c4
-rw-r--r--support/Makefile5
-rw-r--r--support/links-dso-program-c.c20
-rw-r--r--sysdeps/generic/eloop-threshold.h72
-rw-r--r--sysdeps/generic/ldsodefs.h14
-rw-r--r--sysdeps/generic/min-eloop-threshold.h42
-rw-r--r--sysdeps/mach/hurd/i386/libc.abilist1
-rw-r--r--sysdeps/mach/hurd/min-eloop-threshold.h (renamed from sysdeps/mach/hurd/eloop-threshold.h)14
-rw-r--r--sysdeps/mach/hurd/sysconf.c4
-rw-r--r--sysdeps/mach/hurd/x86_64/libc.abilist1
-rw-r--r--sysdeps/mach/readonly-area-fallback.c (renamed from sysdeps/mach/readonly-area.c)11
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/alpha/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/arc/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/arm/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/arm/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/csky/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/i386/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/or1k/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/readonly-area-fallback.c (renamed from sysdeps/unix/sysv/linux/readonly-area.c)21
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sh/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sh/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist1
74 files changed, 707 insertions, 164 deletions
diff --git a/Makeconfig b/Makeconfig
index aa547a4..a2ea4f6 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -442,7 +442,8 @@ ifndef +link-pie
$(filter-out $(addprefix $(csu-objpfx),start.o \
S$(start-installed-name))\
$(+preinit) $(link-extra-libs) \
- $(common-objpfx)libc% $(+postinit),$^) \
+ $(common-objpfx)libc% $(+postinit) \
+ $(+nolink-deps),$^) \
$(link-extra-libs)
+link-pie-after-libc = $(+postctorS) $(+postinit)
define +link-pie
@@ -473,7 +474,8 @@ ifndef +link-static
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
$(+preinit) $(link-extra-libs-static) \
- $(common-objpfx)libc% $(+postinit),$^) \
+ $(common-objpfx)libc% $(+postinit) \
+ $(+nolink-deps), $^) \
$(link-extra-libs-static)
+link-static-after-libc = $(+postctorT) $(+postinit)
define +link-static
@@ -509,7 +511,8 @@ else # not build-pie-default
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
$(+preinit) $(link-extra-libs) \
- $(common-objpfx)libc% $(+postinit),$^) \
+ $(common-objpfx)libc% $(+postinit) \
+ $(+nolink-deps),$^) \
$(link-extra-libs)
+link-after-libc = $(+postctor) $(+postinit)
define +link
@@ -549,7 +552,8 @@ endif # +link
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-name-2.0))\
$(+preinit) $(link-extra-libs) \
- $(common-objpfx)libc% $(+postinit),$^) \
+ $(common-objpfx)libc% $(+postinit) \
+ $(+nolink-deps),$^) \
$(link-extra-libs)
+link-after-libc = $(+postctor) $(+postinit)
define +link-2.0-tests
@@ -633,7 +637,7 @@ link-libc-printers-tests = $(link-libc-rpath) \
$(link-libc-tests-after-rpath-link)
# This is how to find at build-time things that will be installed there.
-rpath-dirs = math elf dlfcn nss nis rt resolv mathvec support misc
+rpath-dirs = math elf dlfcn nss nis rt resolv mathvec support misc debug
rpath-link = \
$(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%)))
else # build-static
diff --git a/Makerules b/Makerules
index ada6168..9dc60cc 100644
--- a/Makerules
+++ b/Makerules
@@ -587,7 +587,7 @@ endef
build-module-helper-objlist = \
$(patsubst %_pic.a,$(whole-archive) %_pic.a $(no-whole-archive),\
$(filter-out %.lds $(map-file) $(+preinit) $(+postinit) \
- $(elf-objpfx)sofini.os \
+ $(elf-objpfx)sofini.os $(+nolink-deps) \
$(link-libc-deps),$^))
build-module-objlist = $(build-module-helper-objlist) $(LDLIBS-$(@F:%.so=%).so)
diff --git a/configure b/configure
index 674d1d7..d11dcf9 100755
--- a/configure
+++ b/configure
@@ -9135,6 +9135,46 @@ fi
config_vars="$config_vars
enable-static-pie = $libc_cv_static_pie"
+# Check if we can link support functionality against libgcc_s.
+# Must not be used for linking installed binaries, to produce the
+# same binaries for bootstrapped and bootstrapping builds (the latter
+# with a GCC that does not build libgcc_s).
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC can link against -lgcc_s" >&5
+printf %s "checking whether $CC can link against -lgcc_s... " >&6; }
+if test ${libc_cv_have_libgcc_s+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) old_LIBS="$LIBS"
+ LIBS="$LIBS -lgcc_s"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main (void)
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"
+then :
+ libc_cv_have_libgcc_s=yes
+else case e in #(
+ e) libc_cv_have_libgcc_s=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$old_LIBS" ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_have_libgcc_s" >&5
+printf "%s\n" "$libc_cv_have_libgcc_s" >&6; }
+config_vars="$config_vars
+have-libgcc_s = $libc_cv_have_libgcc_s"
+
# Support configure.ac under sysdeps.
diff --git a/configure.ac b/configure.ac
index 57cd24c..d068bb5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2061,6 +2061,18 @@ if test "$libc_cv_static_pie" = "yes"; then
fi
LIBC_CONFIG_VAR([enable-static-pie], [$libc_cv_static_pie])
+# Check if we can link support functionality against libgcc_s.
+# Must not be used for linking installed binaries, to produce the
+# same binaries for bootstrapped and bootstrapping builds (the latter
+# with a GCC that does not build libgcc_s).
+AC_CACHE_CHECK([whether $CC can link against -lgcc_s], libc_cv_have_libgcc_s, [dnl
+ old_LIBS="$LIBS"
+ LIBS="$LIBS -lgcc_s"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [libc_cv_have_libgcc_s=yes], [libc_cv_have_libgcc_s=no])
+ LIBS="$old_LIBS"])
+LIBC_CONFIG_VAR([have-libgcc_s], [$libc_cv_have_libgcc_s])
+
# Support configure.ac under sysdeps.
AC_SUBST(libc_cv_test_cc_mprefer_vector_width)
AC_SUBST(test_enable_cet)
diff --git a/debug/Makefile b/debug/Makefile
index 6a05205..2484580 100644
--- a/debug/Makefile
+++ b/debug/Makefile
@@ -55,6 +55,7 @@ routines = \
gethostname_chk \
gets_chk \
getwd_chk \
+ inet_ntop_chk \
longjmp_chk \
mbsnrtowcs_chk \
mbsrtowcs_chk \
@@ -74,6 +75,7 @@ routines = \
readlink_chk \
readlinkat_chk \
readonly-area \
+ readonly-area-fallback \
realpath_chk \
recv_chk \
recvfrom_chk \
@@ -179,9 +181,15 @@ CPPFLAGS-tst-longjmp_chk3.c += $(no-fortify-source) -D_FORTIFY_SOURCE=1
CPPFLAGS-tst-realpath-chk.c += $(no-fortify-source) -D_FORTIFY_SOURCE=2
CPPFLAGS-tst-chk-cancel.c += $(no-fortify-source) -D_FORTIFY_SOURCE=2
CFLAGS-tst-sprintf-fortify-rdonly.c += $(no-fortify-source) -D_FORTIFY_SOURCE=2
+CFLAGS-tst-sprintf-fortify-rdonly-mod.c += $(no-fortify-source) -D_FORTIFY_SOURCE=2
+CFLAGS-tst-sprintf-fortify-rdonly-dlopen.c += $(no-fortify-source) -D_FORTIFY_SOURCE=2
CFLAGS-tst-fortify-syslog.c += $(no-fortify-source) -D_FORTIFY_SOURCE=2
CFLAGS-tst-fortify-wide.c += $(no-fortify-source) -D_FORTIFY_SOURCE=2
+$(objpfx)tst-sprintf-fortify-rdonly: \
+ $(objpfx)tst-sprintf-fortify-rdonly-mod.so \
+ $(objpfx)tst-sprintf-fortify-rdonly-dlopen.so
+
# _FORTIFY_SOURCE tests.
# Auto-generate tests for _FORTIFY_SOURCE for different levels, compilers and
# preprocessor conditions based on tst-fortify.c.
@@ -302,6 +310,11 @@ tests-container += \
tst-fortify-syslog \
# tests-container
+modules-names += \
+ tst-sprintf-fortify-rdonly-dlopen \
+ tst-sprintf-fortify-rdonly-mod \
+ # modules-names
+
ifeq ($(have-ssp),yes)
tests += tst-ssp-1
endif
diff --git a/debug/Versions b/debug/Versions
index 9cf2725..2ae5747 100644
--- a/debug/Versions
+++ b/debug/Versions
@@ -64,6 +64,9 @@ libc {
__wcslcat_chk;
__wcslcpy_chk;
}
+ GLIBC_2.42 {
+ __inet_ntop_chk;
+ }
GLIBC_PRIVATE {
__fortify_fail;
}
diff --git a/debug/inet_ntop_chk.c b/debug/inet_ntop_chk.c
new file mode 100644
index 0000000..e1ec600
--- /dev/null
+++ b/debug/inet_ntop_chk.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/inet.h>
+#include <stdio.h>
+
+const char *
+__inet_ntop_chk (int af, const void *src, char *dst,
+ socklen_t size, size_t dst_size)
+{
+ if (size > dst_size)
+ __chk_fail ();
+
+ return __inet_ntop (af, src, dst, size);
+}
+libc_hidden_def (__inet_ntop_chk)
diff --git a/debug/readonly-area.c b/debug/readonly-area.c
index 04b437e..4311b82 100644
--- a/debug/readonly-area.c
+++ b/debug/readonly-area.c
@@ -16,18 +16,19 @@
<https://www.gnu.org/licenses/>. */
#include <stdlib.h>
+#include <ldsodefs.h>
-/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
- Return -1 if it is writable. */
-
-int
+enum readonly_error_type
__readonly_area (const void *ptr, size_t size)
{
- /* We cannot determine in general whether memory is writable or not.
- This must be handled in a system-dependent manner. to not
- unconditionally break code we need to return here a positive
- answer. This disables this security measure but that is the
- price people have to pay for using systems without a real
- implementation of this interface. */
- return 1;
+ switch (GLRO(dl_readonly_area (ptr, size)))
+ {
+ case dl_readonly_area_rdonly:
+ return readonly_noerror;
+ case dl_readonly_area_writable:
+ return readonly_area_writable;
+ default:
+ break;
+ }
+ return __readonly_area_fallback (ptr, size);
}
diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
index f8ccc2d..cd64936 100644
--- a/debug/tst-fortify.c
+++ b/debug/tst-fortify.c
@@ -23,6 +23,7 @@
#include <assert.h>
#include <fcntl.h>
+#include <arpa/inet.h>
#include <limits.h>
#include <locale.h>
#include <obstack.h>
@@ -1832,6 +1833,26 @@ do_test (void)
# endif
#endif
+ struct in6_addr addr6 = {};
+ struct in_addr addr = {};
+ char addrstr6[INET6_ADDRSTRLEN];
+ char addrstr[INET_ADDRSTRLEN];
+
+ if (inet_ntop (AF_INET6, &addr6, addrstr6, sizeof (addrstr6)) == NULL)
+ FAIL ();
+ if (inet_ntop (AF_INET, &addr, addrstr, sizeof (addrstr)) == NULL)
+ FAIL ();
+
+#if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ inet_ntop (AF_INET6, &addr6, buf, INET6_ADDRSTRLEN);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN);
+ CHK_FAIL_END
+#endif
+
return ret;
}
diff --git a/debug/tst-sprintf-fortify-rdonly-dlopen.c b/debug/tst-sprintf-fortify-rdonly-dlopen.c
new file mode 100644
index 0000000..7da3f51
--- /dev/null
+++ b/debug/tst-sprintf-fortify-rdonly-dlopen.c
@@ -0,0 +1 @@
+#include "tst-sprintf-fortify-rdonly-mod.c"
diff --git a/debug/tst-sprintf-fortify-rdonly-mod.c b/debug/tst-sprintf-fortify-rdonly-mod.c
new file mode 100644
index 0000000..3655f27
--- /dev/null
+++ b/debug/tst-sprintf-fortify-rdonly-mod.c
@@ -0,0 +1,56 @@
+/* Testcase for BZ 30932.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static const char *str2 = "F";
+static char writeable_format[10] = "%s";
+static char relro_format[10] __attribute__ ((section (".data.rel.ro"))) =
+ "%s%n%s%n";
+
+void
+init_writable (void)
+{
+ strcpy (writeable_format + 2, "%n%s%n");
+}
+
+int
+sprintf_writable (int *n1, int *n2)
+{
+ char buf[128];
+ return sprintf (buf, writeable_format, str2, n1, str2, n2);
+}
+
+int
+sprintf_relro (int *n1, int *n2)
+{
+ char buf[128];
+ return sprintf (buf, relro_format, str2, n1, str2, n2);
+}
+
+int
+sprintf_writable_malloc (int *n1, int *n2)
+{
+ char buf[128];
+ char *buf2_malloc = strdup (writeable_format);
+ if (buf2_malloc == NULL)
+ abort ();
+ return sprintf (buf, buf2_malloc, str2, n1, str2, n2);
+}
diff --git a/debug/tst-sprintf-fortify-rdonly.c b/debug/tst-sprintf-fortify-rdonly.c
index ba5a791..fafc834 100644
--- a/debug/tst-sprintf-fortify-rdonly.c
+++ b/debug/tst-sprintf-fortify-rdonly.c
@@ -27,16 +27,64 @@
#include <support/check.h>
#include <support/support.h>
#include <support/temp_file.h>
+#include <support/xdlfcn.h>
-jmp_buf chk_fail_buf;
-bool chk_fail_ok;
+static sigjmp_buf chk_fail_buf;
+static volatile int ret;
+static bool chk_fail_ok;
-const char *str2 = "F";
-char buf2[10] = "%s";
+static void
+handler (int sig)
+{
+ if (chk_fail_ok)
+ {
+ chk_fail_ok = false;
+ longjmp (chk_fail_buf, 1);
+ }
+ else
+ _exit (127);
+}
+
+#define FORTIFY_FAIL \
+ do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0)
+#define CHK_FAIL_START \
+ chk_fail_ok = true; \
+ if (! sigsetjmp (chk_fail_buf, 1)) \
+ {
+#define CHK_FAIL_END \
+ chk_fail_ok = false; \
+ FORTIFY_FAIL; \
+ }
+
+static const char *str2 = "F";
+static char writeable_format[10] = "%s";
+static char relro_format[10] __attribute__ ((section (".data.rel.ro"))) =
+ "%s%n%s%n";
+
+extern void init_writable (void);
+extern int sprintf_writable (int *, int *);
+extern int sprintf_relro (int *, int *);
+extern int sprintf_writable_malloc (int *, int *);
+
+#define str(__x) # __x
+void (*init_writable_dlopen)(void);
+int (*sprintf_writable_dlopen)(int *, int *);
+int (*sprintf_rdonly_dlopen)(int *, int *);
+int (*sprintf_writable_malloc_dlopen)(int *, int *);
static int
do_test (void)
{
+ set_fortify_handler (handler);
+
+ {
+ void *h = xdlopen ("tst-sprintf-fortify-rdonly-dlopen.so", RTLD_NOW);
+ init_writable_dlopen = xdlsym (h, str(init_writable));
+ sprintf_writable_dlopen = xdlsym (h, str(sprintf_writable));
+ sprintf_rdonly_dlopen = xdlsym (h, str(sprintf_relro));
+ sprintf_writable_malloc_dlopen = xdlsym (h, str(sprintf_writable_malloc));
+ }
+
struct rlimit rl;
int max_fd = 24;
@@ -63,20 +111,94 @@ do_test (void)
}
TEST_VERIFY_EXIT (nfiles != 0);
- /* When the format string is writable and contains %n,
- with -D_FORTIFY_SOURCE=2 it causes __chk_fail. However, if libc can not
- open procfs to check if the input format string in within a writable
- memory segment, the fortify version can not perform the check. */
- char buf[128];
- int n1;
- int n2;
-
- strcpy (buf2 + 2, "%n%s%n");
- if (sprintf (buf, buf2, str2, &n1, str2, &n2) != 2
- || n1 != 1 || n2 != 2)
- FAIL_EXIT1 ("sprintf failed: %s %d %d", buf, n1, n2);
-
- return 0;
+ strcpy (writeable_format + 2, "%n%s%n");
+ init_writable ();
+ init_writable_dlopen ();
+
+ /* writeable_format is at a writable part of .bss segment, so libc should be
+ able to check it without resorting to procfs. */
+ {
+ char buf[128];
+ int n1;
+ int n2;
+ CHK_FAIL_START
+ sprintf (buf, writeable_format, str2, &n1, str2, &n2);
+ CHK_FAIL_END
+ }
+
+ /* Same as before, but from an library. */
+ {
+ int n1;
+ int n2;
+ CHK_FAIL_START
+ sprintf_writable (&n1, &n2);
+ CHK_FAIL_END
+ }
+
+ {
+ int n1;
+ int n2;
+ CHK_FAIL_START
+ sprintf_writable_dlopen (&n1, &n2);
+ CHK_FAIL_END
+ }
+
+ /* relro_format is at a readonly part of .bss segment, so '%n' in format input
+ should not trigger a fortify failure. */
+ {
+ char buf[128];
+ int n1;
+ int n2;
+ if (sprintf (buf, relro_format, str2, &n1, str2, &n2) != 2
+ || n1 != 1 || n2 != 2)
+ FAIL_EXIT1 ("sprintf failed: %s %d %d", buf, n1, n2);
+ }
+
+ /* Same as before, but from an library. */
+ {
+ int n1;
+ int n2;
+ if (sprintf_relro (&n1, &n2) != 2 || n1 != 1 || n2 != 2)
+ FAIL_EXIT1 ("sprintf failed: %d %d", n1, n2);
+ }
+
+ {
+ int n1;
+ int n2;
+ if (sprintf_rdonly_dlopen (&n1, &n2) != 2 || n1 != 1 || n2 != 2)
+ FAIL_EXIT1 ("sprintf failed: %d %d", n1, n2);
+ }
+
+ /* However if the format string is placed on a writable memory not covered
+ by ELF segments, libc needs to resort to procfs. */
+ {
+ char buf[128];
+ int n1;
+ int n2;
+ char *buf2_malloc = xstrdup (writeable_format);
+ CHK_FAIL_START
+ sprintf (buf, buf2_malloc, str2, &n1, str2, &n2);
+ CHK_FAIL_END
+ }
+
+ /* Same as before, but from an library. */
+ {
+ int n1;
+ int n2;
+ CHK_FAIL_START
+ sprintf_writable_malloc (&n1, &n2);
+ CHK_FAIL_END
+ }
+
+ {
+ int n1;
+ int n2;
+ CHK_FAIL_START
+ sprintf_writable_malloc_dlopen (&n1, &n2);
+ CHK_FAIL_END
+ }
+
+ return ret;
}
#include <support/test-driver.c>
diff --git a/elf/Makefile b/elf/Makefile
index 3d60000..1282a5b 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -72,6 +72,7 @@ dl-routines = \
dl-open \
dl-origin \
dl-printf \
+ dl-readonly-area \
dl-reloc \
dl-runtime \
dl-scope \
@@ -3451,8 +3452,11 @@ $(objpfx)tst-dlopen-constructor-null-mod2.so: \
CFLAGS-tst-origin.c += $(no-stack-protector)
CFLAGS-liborigin-mod.c += $(no-stack-protector)
+# Link tst-origin with liborigin-mod.so, but without a full path.
LDFLAGS-tst-origin += -Wl,-rpath,\$$ORIGIN -L$(subst :, -L,$(rpath-link)) -lorigin-mod
-$(objpfx)tst-origin.out: tst-origin.sh $(objpfx)liborigin-mod.so $(objpfx)tst-origin
+$(objpfx)tst-origin: +nolink-deps += $(objpfx)liborigin-mod.so
+$(objpfx)tst-origin: $(objpfx)liborigin-mod.so
+$(objpfx)tst-origin.out: tst-origin.sh $(objpfx)tst-origin
$(SHELL) \
$< \
'$(common-objpfx)' \
diff --git a/elf/chroot_canon.c b/elf/chroot_canon.c
index 5db13c2..34869f1 100644
--- a/elf/chroot_canon.c
+++ b/elf/chroot_canon.c
@@ -23,8 +23,7 @@
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
-
-#include <eloop-threshold.h>
+#include <min-eloop-threshold.h>
#include <ldconfig.h>
#ifndef PATH_MAX
@@ -126,7 +125,7 @@ chroot_canon (const char *chroot, const char *name)
char *buf = alloca (PATH_MAX);
size_t len;
- if (++num_links > __eloop_threshold ())
+ if (++num_links > MIN_ELOOP_THRESHOLD)
{
__set_errno (ELOOP);
goto error;
diff --git a/elf/dl-readonly-area.c b/elf/dl-readonly-area.c
new file mode 100644
index 0000000..22769ec
--- /dev/null
+++ b/elf/dl-readonly-area.c
@@ -0,0 +1,86 @@
+/* Check if range is within a read-only from a loaded ELF object.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <ldsodefs.h>
+
+static bool
+check_relro (const struct link_map *l, uintptr_t start, uintptr_t end)
+{
+ if (l->l_relro_addr != 0)
+ {
+ uintptr_t relro_start = ALIGN_DOWN (l->l_addr + l->l_relro_addr,
+ GLRO(dl_pagesize));
+ uintptr_t relro_end = ALIGN_DOWN (l->l_addr + l->l_relro_addr
+ + l->l_relro_size,
+ GLRO(dl_pagesize));
+ /* RELRO is caved out from a RW segment, so the next range is either
+ RW or nonexistent. */
+ return relro_start <= start && end <= relro_end
+ ? dl_readonly_area_rdonly : dl_readonly_area_writable;
+
+ }
+ return dl_readonly_area_writable;
+}
+
+enum dl_readonly_area_error_type
+_dl_readonly_area (const void *ptr, size_t size)
+{
+ struct dl_find_object dlfo;
+ if (_dl_find_object ((void *)ptr, &dlfo) != 0)
+ return dl_readonly_area_not_found;
+
+ const struct link_map *l = dlfo.dlfo_link_map;
+ uintptr_t ptr_start = (uintptr_t) ptr;
+ uintptr_t ptr_end = ptr_start + size;
+
+ for (const ElfW(Phdr) *ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
+ if (ph->p_type == PT_LOAD)
+ {
+ /* For segments with alignment larger than the page size,
+ _dl_map_segment allocates additional space that is mark as
+ PROT_NONE (so we can ignore). */
+ uintptr_t from = l->l_addr
+ + ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize));
+ uintptr_t to = l->l_addr
+ + ALIGN_UP (ph->p_vaddr + ph->p_filesz, GLRO(dl_pagesize));
+
+ /* Found an entry that at least partially covers the area. */
+ if (from < ptr_end && to > ptr_start)
+ {
+ if (ph->p_flags & PF_W)
+ return check_relro (l, ptr_start, ptr_end);
+
+ if ((ph->p_flags & PF_R) == 0)
+ return dl_readonly_area_writable;
+
+ if (from <= ptr_start && to >= ptr_end)
+ return dl_readonly_area_rdonly;
+ else if (from <= ptr_start)
+ size -= to - ptr_start;
+ else if (to >= ptr_end)
+ size -= ptr_end - from;
+ else
+ size -= to - from;
+
+ if (size == 0)
+ break;
+ }
+ }
+
+ return size == 0 ? dl_readonly_area_rdonly : dl_readonly_area_not_found;
+}
diff --git a/elf/rtld.c b/elf/rtld.c
index 00b25c1..099c447 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -371,6 +371,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
._dl_error_free = _dl_error_free,
._dl_tls_get_addr_soft = _dl_tls_get_addr_soft,
._dl_libc_freeres = __rtld_libc_freeres,
+ ._dl_readonly_area = _dl_readonly_area,
};
/* If we would use strong_alias here the compiler would see a
non-hidden definition. This would undo the effect of the previous
diff --git a/hurd/lookup-retry.c b/hurd/lookup-retry.c
index 6b94a10..ac8925e 100644
--- a/hurd/lookup-retry.c
+++ b/hurd/lookup-retry.c
@@ -24,7 +24,7 @@
#include <fcntl.h>
#include <string.h>
#include <_itoa.h>
-#include <eloop-threshold.h>
+#include <min-eloop-threshold.h>
#include <unistd.h>
/* Translate the error from dir_lookup into the error the user sees. */
@@ -113,7 +113,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
/* Fall through. */
case FS_RETRY_NORMAL:
- if (nloops++ >= __eloop_threshold ())
+ if (nloops++ >= MIN_ELOOP_THRESHOLD)
{
__mach_port_deallocate (__mach_task_self (), *result);
err = ELOOP;
@@ -207,7 +207,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
dirport = INIT_PORT_CRDIR;
if (*result != MACH_PORT_NULL)
__mach_port_deallocate (__mach_task_self (), *result);
- if (nloops++ >= __eloop_threshold ())
+ if (nloops++ >= MIN_ELOOP_THRESHOLD)
{
err = ELOOP;
goto out;
diff --git a/include/arpa/inet.h b/include/arpa/inet.h
index d9e55a3..a02892f 100644
--- a/include/arpa/inet.h
+++ b/include/arpa/inet.h
@@ -3,12 +3,18 @@
#include <inet/arpa/inet.h>
#ifndef _ISOMAC
+/* Declare functions with security checks.
+ This needs to be included unconditionally as these definition are needed even
+ when fortification is disabled in inet/arpa/inet.h. */
+#include <bits/inet-fortified-decl.h>
+
/* Variant of inet_aton which rejects trailing garbage. */
extern int __inet_aton_exact (const char *__cp, struct in_addr *__inp);
libc_hidden_proto (__inet_aton_exact)
extern __typeof (inet_ntop) __inet_ntop;
libc_hidden_proto (__inet_ntop)
+libc_hidden_proto (__inet_ntop_chk)
libc_hidden_proto (inet_pton)
extern __typeof (inet_pton) __inet_pton;
diff --git a/include/bits/inet-fortified-decl.h b/include/bits/inet-fortified-decl.h
new file mode 100644
index 0000000..e6ad4d4
--- /dev/null
+++ b/include/bits/inet-fortified-decl.h
@@ -0,0 +1 @@
+#include <inet/bits/inet-fortified-decl.h>
diff --git a/include/bits/inet-fortified.h b/include/bits/inet-fortified.h
new file mode 100644
index 0000000..abba7c5
--- /dev/null
+++ b/include/bits/inet-fortified.h
@@ -0,0 +1 @@
+#include <inet/bits/inet-fortified.h>
diff --git a/include/stdlib.h b/include/stdlib.h
index 57f4ab8..b7147ba 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -368,6 +368,21 @@ struct abort_msg_s
extern struct abort_msg_s *__abort_msg;
libc_hidden_proto (__abort_msg)
+enum readonly_error_type
+{
+ readonly_noerror,
+ readonly_area_writable,
+ readonly_procfs_inaccessible,
+ readonly_procfs_open_fail,
+};
+
+extern enum readonly_error_type __readonly_area (const void *ptr,
+ size_t size)
+ attribute_hidden;
+extern enum readonly_error_type __readonly_area_fallback (const void *ptr,
+ size_t size)
+ attribute_hidden;
+
# if IS_IN (rtld)
extern __typeof (unsetenv) unsetenv attribute_hidden;
extern __typeof (__strtoul_internal) __strtoul_internal attribute_hidden;
diff --git a/inet/Makefile b/inet/Makefile
index 79bacdd..104b582 100644
--- a/inet/Makefile
+++ b/inet/Makefile
@@ -25,6 +25,8 @@ include ../Makeconfig
headers := \
$(wildcard arpa/*.h protocols/*.h) \
bits/in.h \
+ bits/inet-fortified-decl.h \
+ bits/inet-fortified.h \
ifaddrs.h \
netinet/ether.h \
netinet/icmp6.h \
diff --git a/inet/arpa/inet.h b/inet/arpa/inet.h
index 42d38c3..3083676 100644
--- a/inet/arpa/inet.h
+++ b/inet/arpa/inet.h
@@ -101,6 +101,11 @@ extern char *inet_nsap_ntoa (int __len, const unsigned char *__cp,
char *__buf) __THROW;
#endif
+#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
+/* Include functions with security checks. */
+# include <bits/inet-fortified.h>
+#endif
+
__END_DECLS
#endif /* arpa/inet.h */
diff --git a/inet/bits/inet-fortified-decl.h b/inet/bits/inet-fortified-decl.h
new file mode 100644
index 0000000..23e3cf4
--- /dev/null
+++ b/inet/bits/inet-fortified-decl.h
@@ -0,0 +1,35 @@
+/* Declarations of checking macros for inet functions.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_INET_FORTIFIED_DEC_H
+#define _BITS_INET_FORTIFIED_DEC_H 1
+
+#ifndef _ARPA_INET_H
+# error "Never include <bits/inet-fortified-decl.h> directly; use <arpa/inet.h> instead."
+#endif
+
+extern const char *__inet_ntop_chk (int, const void *, char *, socklen_t, size_t);
+
+extern const char *__REDIRECT_FORTIFY_NTH (__inet_ntop_alias,
+ (int, const void *, char *, socklen_t), inet_ntop);
+extern const char *__REDIRECT_NTH (__inet_ntop_chk_warn,
+ (int, const void *, char *, socklen_t, size_t), __inet_ntop_chk)
+ __warnattr ("inet_ntop called with bigger length than "
+ "size of destination buffer");
+
+#endif /* bits/inet-fortified-decl.h. */
diff --git a/inet/bits/inet-fortified.h b/inet/bits/inet-fortified.h
new file mode 100644
index 0000000..4f6bc34
--- /dev/null
+++ b/inet/bits/inet-fortified.h
@@ -0,0 +1,41 @@
+/* Checking macros for inet functions.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_INET_FORTIFIED_H
+#define _BITS_INET_FORTIFIED_H 1
+
+#ifndef _ARPA_INET_H
+# error "Never include <bits/inet-fortified.h> directly; use <arpa/inet.h> instead."
+#endif
+
+#include <bits/inet-fortified-decl.h>
+
+__fortify_function __attribute_overloadable__ const char *
+__NTH (inet_ntop (int __af,
+ __fortify_clang_overload_arg (const void *, __restrict, __src),
+ char *__restrict __dst, socklen_t __dst_size))
+ __fortify_clang_warning_only_if_bos_lt (__dst_size, __dst,
+ "inet_ntop called with bigger length "
+ "than size of destination buffer")
+{
+ return __glibc_fortify (inet_ntop, __dst_size, sizeof (char),
+ __glibc_objsize (__dst),
+ __af, __src, __dst, __dst_size);
+};
+
+#endif /* bits/inet-fortified.h. */
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 55fb2ab..b73ddbf 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3692,6 +3692,8 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
}
size_t tc_idx = csize2tidx (tbytes);
+ MAYBE_INIT_TCACHE ();
+
if (tcache_available (tc_idx))
{
/* The tcache itself isn't encoded, but the chain is. */
diff --git a/manual/maint.texi b/manual/maint.texi
index 04faa22..ce6a556 100644
--- a/manual/maint.texi
+++ b/manual/maint.texi
@@ -303,6 +303,8 @@ The following functions and macros are fortified in @theglibc{}:
@item @code{getwd}
+@item @code{inet_ntop}
+
@item @code{longjmp}
@item @code{mbsnrtowcs}
diff --git a/stdio-common/vfprintf-internal.c b/stdio-common/vfprintf-internal.c
index aa9708b..fa41e1b 100644
--- a/stdio-common/vfprintf-internal.c
+++ b/stdio-common/vfprintf-internal.c
@@ -576,7 +576,8 @@ static const uint8_t jump_table[] =
/* Handle positional format specifiers. */
static void printf_positional (struct Xprintf_buffer *buf,
- const CHAR_T *format, int readonly_format,
+ const CHAR_T *format,
+ enum readonly_error_type readonly_format,
va_list ap, va_list *ap_savep,
int nspecs_done, const UCHAR_T *lead_str_end,
CHAR_T *work_buffer, int save_errno,
@@ -626,9 +627,7 @@ Xprintf_buffer (struct Xprintf_buffer *buf, const CHAR_T *format,
/* For the %m format we may need the current `errno' value. */
int save_errno = errno;
- /* 1 if format is in read-only memory, -1 if it is in writable memory,
- 0 if unknown. */
- int readonly_format = 0;
+ enum readonly_error_type readonly_format = readonly_noerror;
/* Initialize local variables. */
grouping = (const char *) -1;
@@ -1045,7 +1044,7 @@ do_positional:
static void
printf_positional (struct Xprintf_buffer * buf, const CHAR_T *format,
- int readonly_format,
+ enum readonly_error_type readonly_format,
va_list ap, va_list *ap_savep, int nspecs_done,
const UCHAR_T *lead_str_end,
CHAR_T *work_buffer, int save_errno,
diff --git a/stdio-common/vfprintf-process-arg.c b/stdio-common/vfprintf-process-arg.c
index 8d20493..90b5e61 100644
--- a/stdio-common/vfprintf-process-arg.c
+++ b/stdio-common/vfprintf-process-arg.c
@@ -324,16 +324,24 @@ LABEL (form_pointer):
LABEL (form_number):
if ((mode_flags & PRINTF_FORTIFY) != 0)
{
- if (! readonly_format)
- {
- extern int __readonly_area (const void *, size_t)
- attribute_hidden;
- readonly_format
- = __readonly_area (format, ((STR_LEN (format) + 1)
- * sizeof (CHAR_T)));
- }
- if (readonly_format < 0)
- __libc_fatal ("*** %n in writable segment detected ***\n");
+ if (readonly_format == readonly_noerror)
+ readonly_format = __readonly_area (format, ((STR_LEN (format) + 1)
+ * sizeof (CHAR_T)));
+ switch (readonly_format)
+ {
+ case readonly_area_writable:
+ __libc_fatal ("*** %n in writable segments detected ***\n");
+ /* The format is not within ELF segments and opening /proc/self/maps
+ failed because there are too many files. */
+ case readonly_procfs_open_fail:
+ __libc_fatal ("*** procfs could not open ***\n");
+ /* The /proc/self/maps can not be opened either because it is not
+ available or the process does not have the right permission. Since
+ it should not be attacker-controlled we can avoid failure. */
+ case readonly_procfs_inaccessible:
+ case readonly_noerror:
+ break;
+ }
}
/* Answer the count of characters written. */
void *ptrptr = process_arg_pointer ();
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index 528bf49..dca6fca 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -36,17 +36,19 @@
#include <sys/stat.h>
#include <unistd.h>
-#include <eloop-threshold.h>
#include <filename.h>
#include <idx.h>
#include <intprops.h>
#include <scratch_buffer.h>
#ifdef _LIBC
+# include <min-eloop-threshold.h>
# include <shlib-compat.h>
# define GCC_LINT 1
# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
#else
+# include <eloop-threshold.h>
+# define MIN_ELOOP_THRESHOLD __eloop_threshold ()
# define __canonicalize_file_name canonicalize_file_name
# define __realpath realpath
# define __strdup strdup
@@ -310,7 +312,7 @@ realpath_stk (const char *name, char *resolved, struct realpath_bufs *bufs)
}
if (0 <= n)
{
- if (++num_links > __eloop_threshold ())
+ if (++num_links > MIN_ELOOP_THRESHOLD)
{
__set_errno (ELOOP);
goto error;
diff --git a/stdlib/tst-canon-bz26341.c b/stdlib/tst-canon-bz26341.c
index a9b823b..b62b2ca 100644
--- a/stdlib/tst-canon-bz26341.c
+++ b/stdlib/tst-canon-bz26341.c
@@ -23,7 +23,7 @@
#include <unistd.h>
#define __sysconf sysconf
-#include <eloop-threshold.h>
+#include <min-eloop-threshold.h>
#include <support/check.h>
#include <support/support.h>
#include <support/temp_file.h>
@@ -54,7 +54,7 @@ create_link (void)
/* Create MAXLINKS symbolic links to the temporary filename.
On exit, linkname has the last link created. */
char *prevlink = filename;
- int maxlinks = __eloop_threshold ();
+ int maxlinks = MIN_ELOOP_THRESHOLD;
for (int i = 0; i < maxlinks; i++)
{
linkname = xasprintf ("%s%d", filename, i);
diff --git a/support/Makefile b/support/Makefile
index 59a9974..ea7b4cd 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -281,6 +281,11 @@ CFLAGS-temp_file.c += -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
ifeq (,$(CXX))
LINKS_DSO_PROGRAM = links-dso-program-c
+CFLAGS-links-dso-program-c.c += -fexceptions
+LDLIBS-links-dso-program-c = -lgcc
+ifeq ($(have-libgcc_s),yes)
+LDLIBS-links-dso-program-c += -lgcc_s $(libunwind)
+endif
else
LINKS_DSO_PROGRAM = links-dso-program
LDLIBS-links-dso-program = -lstdc++ -lgcc -lgcc_s $(libunwind)
diff --git a/support/links-dso-program-c.c b/support/links-dso-program-c.c
index 5fcbab2..efe65b4 100644
--- a/support/links-dso-program-c.c
+++ b/support/links-dso-program-c.c
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <dlfcn.h>
/* makedb needs selinux dso's. */
#ifdef HAVE_SELINUX
@@ -13,6 +14,20 @@
such dependencies.
*/
+/* Use attribute cleanup to force linking against libgcc_s. */
+static void
+cleanup_function (int *ignored)
+{
+ puts ("cleanup performed");
+}
+
+void
+invoke_callback (void (*callback) (int *))
+{
+ __attribute__ ((cleanup (cleanup_function))) int i = 0;
+ callback (&i);
+}
+
int
main (int argc, char **argv)
{
@@ -22,5 +37,10 @@ main (int argc, char **argv)
/* This exists to force libselinux.so to be required. */
printf ("selinux %d\n", is_selinux_enabled ());
#endif
+ /* Prevent invoke_callback from being optimized away. */
+ {
+ Dl_info dli;
+ dladdr (invoke_callback, &dli);
+ }
return 0;
}
diff --git a/sysdeps/generic/eloop-threshold.h b/sysdeps/generic/eloop-threshold.h
deleted file mode 100644
index 0236368..0000000
--- a/sysdeps/generic/eloop-threshold.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Threshold at which to diagnose ELOOP. Generic version.
- Copyright (C) 2012-2025 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
-
-#ifndef _ELOOP_THRESHOLD_H
-#define _ELOOP_THRESHOLD_H 1
-
-#include <limits.h>
-#include <sys/param.h>
-
-/* POSIX specifies SYMLOOP_MAX as the "Maximum number of symbolic
- links that can be reliably traversed in the resolution of a
- pathname in the absence of a loop." This makes it a minimum that
- we should certainly accept. But it leaves open the possibility
- that more might sometimes work--just not "reliably".
-
- For example, Linux implements a complex policy whereby there is a
- small limit on the number of direct symlink traversals (a symlink
- to a symlink to a symlink), but larger limit on the total number of
- symlink traversals overall. Hence the SYMLOOP_MAX number should be
- the small one, but the limit library functions enforce on users
- should be the larger one.
-
- So, we use the larger of the reported SYMLOOP_MAX (if any) and our
- own constant MIN_ELOOP_THRESHOLD, below. This constant should be
- large enough that it never rules out a file name and directory tree
- that the underlying system (i.e. calls to 'open' et al) would
- resolve successfully. It should be small enough that actual loops
- are detected without a huge number of iterations. */
-
-#ifndef MIN_ELOOP_THRESHOLD
-# define MIN_ELOOP_THRESHOLD 40
-#endif
-
-/* Return the maximum number of symlink traversals to permit
- before diagnosing ELOOP. */
-static inline unsigned int __attribute__ ((const))
-__eloop_threshold (void)
-{
-#ifdef SYMLOOP_MAX
- const int symloop_max = SYMLOOP_MAX;
-#else
- /* The function is marked 'const' even though we use memory and
- call a function, because sysconf is required to return the
- same value in every call and so it must always be safe to
- call __eloop_threshold exactly once and reuse the value. */
- static long int sysconf_symloop_max;
- if (sysconf_symloop_max == 0)
- sysconf_symloop_max = __sysconf (_SC_SYMLOOP_MAX);
- const unsigned int symloop_max = (sysconf_symloop_max <= 0
- ? _POSIX_SYMLOOP_MAX
- : sysconf_symloop_max);
-#endif
-
- return MAX (symloop_max, MIN_ELOOP_THRESHOLD);
-}
-
-#endif /* eloop-threshold.h */
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 19494b8..5b12a41 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -276,6 +276,12 @@ struct audit_ifaces
struct audit_ifaces *next;
};
+enum dl_readonly_area_error_type
+{
+ dl_readonly_area_rdonly,
+ dl_readonly_area_writable,
+ dl_readonly_area_not_found,
+};
/* Test whether given NAME matches any of the names of the given object. */
extern int _dl_name_match_p (const char *__name, const struct link_map *__map)
@@ -676,6 +682,10 @@ struct rtld_global_ro
dlopen. */
int (*_dl_find_object) (void *, struct dl_find_object *);
+ /* Implementation of _dl_readonly_area, used in fortify routines to check
+ if memory area is within a read-only ELF segment. */
+ enum dl_readonly_area_error_type (*_dl_readonly_area) (const void *, size_t);
+
/* Dynamic linker operations used after static dlopen. */
const struct dlfcn_hook *_dl_dlfcn_hook;
@@ -1284,6 +1294,10 @@ extern void _dl_show_scope (struct link_map *new, int from)
extern struct link_map *_dl_find_dso_for_object (const ElfW(Addr) addr);
rtld_hidden_proto (_dl_find_dso_for_object)
+extern enum dl_readonly_area_error_type _dl_readonly_area (const void *ptr,
+ size_t size)
+ attribute_hidden;
+
/* Initialization which is normally done by the dynamic linker. */
extern void _dl_non_dynamic_init (void)
attribute_hidden;
diff --git a/sysdeps/generic/min-eloop-threshold.h b/sysdeps/generic/min-eloop-threshold.h
new file mode 100644
index 0000000..2ac12ed
--- /dev/null
+++ b/sysdeps/generic/min-eloop-threshold.h
@@ -0,0 +1,42 @@
+/* Minimum threshold at which to diagnose ELOOP. Generic version.
+ Copyright (C) 2012-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _MIN_ELOOP_THRESHOLD_H
+#define _MIN_ELOOP_THRESHOLD_H 1
+
+/* POSIX specifies SYMLOOP_MAX as the "Maximum number of symbolic
+ links that can be reliably traversed in the resolution of a
+ pathname in the absence of a loop." This makes it a minimum that
+ we should certainly accept. But it leaves open the possibility
+ that more might sometimes work--just not "reliably".
+
+ For example, Linux implements a complex policy whereby there is a
+ small limit on the number of direct symlink traversals (a symlink
+ to a symlink to a symlink), but larger limit on the total number of
+ symlink traversals overall. Hence the SYMLOOP_MAX number should be
+ the small one, but the limit library functions enforce on users
+ should be the larger one.
+
+ This constant should be large enough that it never rules out a file
+ name and directory tree that the underlying system (i.e. calls to 'open'
+ et al) would resolve successfully. It should be small enough that
+ actual loops are detected without a huge number of iterations. */
+
+#define MIN_ELOOP_THRESHOLD 40
+
+#endif
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 461df01..facb01b 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2584,6 +2584,7 @@ GLIBC_2.41 pthread_mutexattr_setrobust F
GLIBC_2.41 pthread_mutexattr_setrobust_np F
GLIBC_2.41 pthread_mutexattr_settype F
GLIBC_2.41 pthread_sigmask F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_barrier_destroy F
GLIBC_2.42 pthread_barrier_init F
GLIBC_2.42 pthread_barrier_wait F
diff --git a/sysdeps/mach/hurd/eloop-threshold.h b/sysdeps/mach/hurd/min-eloop-threshold.h
index 13842b4..98ecf49 100644
--- a/sysdeps/mach/hurd/eloop-threshold.h
+++ b/sysdeps/mach/hurd/min-eloop-threshold.h
@@ -1,4 +1,4 @@
-/* Threshold at which to diagnose ELOOP. Hurd version.
+/* Minimum threshold at which to diagnose ELOOP. Hurd version.
Copyright (C) 2012-2025 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,8 +16,8 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#ifndef _ELOOP_THRESHOLD_H
-#define _ELOOP_THRESHOLD_H 1
+#ifndef _MIN_ELOOP_THRESHOLD_H
+#define _MIN_ELOOP_THRESHOLD_H 1
/* Return the maximum number of symlink traversals to permit
before diagnosing ELOOP.
@@ -28,10 +28,6 @@
but instead use sysconf and the number can be changed here to
affect sysconf's result. */
-static inline unsigned int __attribute__ ((const))
-__eloop_threshold (void)
-{
- return 32;
-}
+#define MIN_ELOOP_THRESHOLD 32
-#endif /* eloop-threshold.h */
+#endif
diff --git a/sysdeps/mach/hurd/sysconf.c b/sysdeps/mach/hurd/sysconf.c
index cb4899a..bf61090 100644
--- a/sysdeps/mach/hurd/sysconf.c
+++ b/sysdeps/mach/hurd/sysconf.c
@@ -19,8 +19,8 @@
#include <limits.h>
#include <unistd.h>
-#include <eloop-threshold.h>
+#include <min-eloop-threshold.h>
-#define SYMLOOP_MAX (__eloop_threshold ())
+#define SYMLOOP_MAX MIN_ELOOP_THRESHOLD
#include <sysdeps/posix/sysconf.c>
diff --git a/sysdeps/mach/hurd/x86_64/libc.abilist b/sysdeps/mach/hurd/x86_64/libc.abilist
index 6f235d2..3c76f6a 100644
--- a/sysdeps/mach/hurd/x86_64/libc.abilist
+++ b/sysdeps/mach/hurd/x86_64/libc.abilist
@@ -2267,6 +2267,7 @@ GLIBC_2.41 pthread_mutexattr_setrobust F
GLIBC_2.41 pthread_mutexattr_setrobust_np F
GLIBC_2.41 pthread_mutexattr_settype F
GLIBC_2.41 pthread_sigmask F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_barrier_destroy F
GLIBC_2.42 pthread_barrier_init F
GLIBC_2.42 pthread_barrier_wait F
diff --git a/sysdeps/mach/readonly-area.c b/sysdeps/mach/readonly-area-fallback.c
index fb89413..3fb8732 100644
--- a/sysdeps/mach/readonly-area.c
+++ b/sysdeps/mach/readonly-area-fallback.c
@@ -20,11 +20,8 @@
#include <stdint.h>
#include <mach.h>
-/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
- Return -1 if it is writable. */
-
-int
-__readonly_area (const char *ptr, size_t size)
+enum readonly_error_type
+__readonly_area_fallback (const void *ptr, size_t size)
{
vm_address_t region_address = (uintptr_t) ptr;
vm_size_t region_length = size;
@@ -46,11 +43,11 @@ __readonly_area (const char *ptr, size_t size)
continue;
if (protection & VM_PROT_WRITE)
- return -1;
+ return readonly_area_writable;
if (region_address - (uintptr_t) ptr >= size)
break;
}
- return 1;
+ return readonly_noerror;
}
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 0889725..afbb38f 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2750,4 +2750,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index b33a52d..ea11409 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -3097,6 +3097,7 @@ GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 0c78cb6..c6edd66 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -2511,4 +2511,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index a4571bf..00e46c2 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -2803,6 +2803,7 @@ GLIBC_2.4 xprt_register F
GLIBC_2.4 xprt_unregister F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index 060ab80..3a87471 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -2800,6 +2800,7 @@ GLIBC_2.4 xprt_register F
GLIBC_2.4 xprt_unregister F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 5c4f912..b819f40 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2787,4 +2787,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index f837bf9..5cb0987 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2824,6 +2824,7 @@ GLIBC_2.4 unshare F
GLIBC_2.41 cacheflush F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 9ea9e65..1ec4812 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -3007,6 +3007,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
index 243422f..82b6b0d 100644
--- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist
@@ -2271,4 +2271,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 88397ad13..03818c4 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -2783,6 +2783,7 @@ GLIBC_2.4 xprt_register F
GLIBC_2.4 xprt_unregister F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 81d6333..a2b3d25 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2950,6 +2950,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 9522c31..bc00403 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2836,4 +2836,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 9e76042..5606a70 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2833,4 +2833,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 8a2df86..5fab619 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2911,6 +2911,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 491a9a8..5ba810d 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2909,6 +2909,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index ee36f59..e1b8f13 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2917,6 +2917,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 083709e..c0ee223 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2819,6 +2819,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
index dc2d61e..227746a 100644
--- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
+++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
@@ -2261,4 +2261,5 @@ GLIBC_2.40 setcontext F
GLIBC_2.40 swapcontext F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 56dfb11..46fd69d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -3140,6 +3140,7 @@ GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 4951295..9887e11 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -3185,6 +3185,7 @@ GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index d161a0e..2600dc2 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2894,6 +2894,7 @@ GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index b2354c9..d803fec 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2970,4 +2970,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/readonly-area.c b/sysdeps/unix/sysv/linux/readonly-area-fallback.c
index 62d2070..c93ad2a 100644
--- a/sysdeps/unix/sysv/linux/readonly-area.c
+++ b/sysdeps/unix/sysv/linux/readonly-area-fallback.c
@@ -23,11 +23,8 @@
#include <string.h>
#include "libio/libioP.h"
-/* Return 1 if the whole area PTR .. PTR+SIZE is not writable.
- Return -1 if it is writable. */
-
-int
-__readonly_area (const char *ptr, size_t size)
+enum readonly_error_type
+__readonly_area_fallback (const void *ptr, size_t size)
{
const void *ptr_end = ptr + size;
@@ -42,11 +39,11 @@ __readonly_area (const char *ptr, size_t size)
to the /proc filesystem if it is set[ug]id. There has
been no willingness to change this in the kernel so
far. */
- || errno == EACCES
- /* Process has reached the maximum number of open files. */
- || errno == EMFILE)
- return 1;
- return -1;
+ || errno == EACCES)
+ return readonly_procfs_inaccessible;
+ /* Process has reached the maximum number of open files or another
+ unusual error. */
+ return readonly_procfs_open_fail;
}
/* We need no locking. */
@@ -98,7 +95,5 @@ __readonly_area (const char *ptr, size_t size)
fclose (fp);
free (line);
- /* If the whole area between ptr and ptr_end is covered by read-only
- VMAs, return 1. Otherwise return -1. */
- return size == 0 ? 1 : -1;
+ return size == 0 ? readonly_noerror : readonly_area_writable;
}
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 931c733..a2646bd 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2514,4 +2514,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.40 __riscv_hwprobe F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 187d184..ad18f29 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2714,4 +2714,5 @@ GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.40 __riscv_hwprobe F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index b05ab0b..2f76c27 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -3138,6 +3138,7 @@ GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index ed29d3e..4ea3369 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2931,6 +2931,7 @@ GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 1f084b0..f245f8f 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2830,6 +2830,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 13c45bc..4c654a5 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2827,6 +2827,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index ba9310b..d89a81e 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -3159,6 +3159,7 @@ GLIBC_2.4 wprintf F
GLIBC_2.4 wscanf F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 13ac7f3..ee7b842 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2795,6 +2795,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 46b6b61..00155d9 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2746,6 +2746,7 @@ GLIBC_2.4 unlinkat F
GLIBC_2.4 unshare F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 1f25723..18765ec 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2765,4 +2765,5 @@ GLIBC_2.39 stdc_trailing_zeros_ull F
GLIBC_2.39 stdc_trailing_zeros_us F
GLIBC_2.41 sched_getattr F
GLIBC_2.41 sched_setattr F
+GLIBC_2.42 __inet_ntop_chk F
GLIBC_2.42 pthread_gettid_np F