Partial backport (without ABI changes, using libc_nonshared.a instead) of: commit e3a6e85d67f1a48dec3e2557a83d6ce1544a58cb Author: Aaron Merey Date: Thu Mar 20 13:13:33 2025 -0400 Add _FORTIFY_SOURCE support for inet_pton Add function __inet_pton_chk which calls __chk_fail when the size of argument dst is too small. inet_pton is redirected to __inet_pton_chk or __inet_pton_warn when _FORTIFY_SOURCE is > 0. Also add tests to debug/tst-fortify.c, update the abilist (Dropped) with __inet_pton_chk and mention inet_pton fortification in maint.texi. Co-authored-by: Frédéric Bérat Reviewed-by: Florian Weimer Conflicts: debug/inet_pton_chk.c (attribute_hidden added, use inet_pton instead of __inet_pton) debug/Makefile (routine added to static-routines-only) debug/Versions (Dropped) inet/bits/inet-fortified.h (removed attribute_overloadable and clang specific handling) sysdeps/mach/hurd/i386/libc.abilist sysdeps/mach/hurd/x86_64/libc.abilist sysdeps/unix/sysv/linux/aarch64/libc.abilist sysdeps/unix/sysv/linux/alpha/libc.abilist sysdeps/unix/sysv/linux/arc/libc.abilist sysdeps/unix/sysv/linux/arm/be/libc.abilist sysdeps/unix/sysv/linux/arm/le/libc.abilist sysdeps/unix/sysv/linux/csky/libc.abilist sysdeps/unix/sysv/linux/hppa/libc.abilist sysdeps/unix/sysv/linux/i386/libc.abilist sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist sysdeps/unix/sysv/linux/microblaze/be/libc.abilist sysdeps/unix/sysv/linux/microblaze/le/libc.abilist sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist sysdeps/unix/sysv/linux/or1k/libc.abilist sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist sysdeps/unix/sysv/linux/sh/be/libc.abilist sysdeps/unix/sysv/linux/sh/le/libc.abilist sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist sysdeps/unix/sysv/linux/x86_64/64/libc.abilist sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist (Dropped) diff --git a/debug/Makefile b/debug/Makefile index a2d236e28eda8b47..5a7295678cb1eed1 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -122,6 +122,7 @@ routines = \ static-only-routines := \ inet_ntop_chk \ + inet_pton_chk \ stack_chk_fail_local \ # static-only-routines # Don't add stack_chk_fail_local.o to libc.a since __stack_chk_fail_local diff --git a/debug/inet_pton_chk.c b/debug/inet_pton_chk.c new file mode 100644 index 0000000000000000..feca3bff5a4ded2f --- /dev/null +++ b/debug/inet_pton_chk.c @@ -0,0 +1,31 @@ +/* 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 + . */ + +#include +#include + +attribute_hidden +int +__inet_pton_chk (int af, const char *src, void *dst, size_t dst_size) +{ + if ((af == AF_INET && dst_size < 4) + || (af == AF_INET6 && dst_size < 16)) + __chk_fail (); + + return inet_pton (af, src, dst); +} +libc_hidden_def (__inet_pton_chk) diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c index f9b97531749d363b..0e44594a181fdba5 100644 --- a/debug/tst-fortify.c +++ b/debug/tst-fortify.c @@ -1853,6 +1853,30 @@ do_test (void) CHK_FAIL_END #endif + const char *ipv4str = "127.0.0.1"; + const char *ipv6str = "::1"; + + if (inet_pton (AF_INET, ipv4str, (void *) &addr) != 1) + FAIL (); + if (inet_pton (AF_INET6, ipv6str, (void *) &addr6) != 1) + FAIL (); + +#if __USE_FORTIFY_LEVEL >= 1 + char smallbuf[2]; + + CHK_FAIL_START + inet_pton (AF_INET, ipv4str, (void *) smallbuf); + CHK_FAIL_END + + CHK_FAIL_START + inet_pton (AF_INET6, ipv6str, (void *) smallbuf); + CHK_FAIL_END + + CHK_FAIL_START + inet_pton (AF_INET6, ipv6str, (void *) &addr); + CHK_FAIL_END +#endif + return ret; } diff --git a/include/arpa/inet.h b/include/arpa/inet.h index a02892f48a27454e..3db8f1a96fdbd6fd 100644 --- a/include/arpa/inet.h +++ b/include/arpa/inet.h @@ -19,6 +19,8 @@ libc_hidden_proto (__inet_ntop_chk) libc_hidden_proto (inet_pton) extern __typeof (inet_pton) __inet_pton; libc_hidden_proto (__inet_pton) +libc_hidden_proto (__inet_pton_chk) + extern __typeof (inet_makeaddr) __inet_makeaddr; libc_hidden_proto (__inet_makeaddr) libc_hidden_proto (inet_netof) diff --git a/inet/bits/inet-fortified-decl.h b/inet/bits/inet-fortified-decl.h index 23e3cf4b2238c81a..748a119f149d790b 100644 --- a/inet/bits/inet-fortified-decl.h +++ b/inet/bits/inet-fortified-decl.h @@ -32,4 +32,11 @@ extern const char *__REDIRECT_NTH (__inet_ntop_chk_warn, __warnattr ("inet_ntop called with bigger length than " "size of destination buffer"); +extern int __inet_pton_chk (int, const char *, void *, size_t); + +extern int __REDIRECT_FORTIFY_NTH (__inet_pton_alias, + (int, const char *, void *), inet_pton); +extern int __REDIRECT_NTH (__inet_pton_chk_warn, + (int, const char *, void *, size_t), __inet_pton_chk) + __warnattr ("inet_pton called with a destination buffer size too small"); #endif /* bits/inet-fortified-decl.h. */ diff --git a/inet/bits/inet-fortified.h b/inet/bits/inet-fortified.h index af26f36ef6ae0533..8420a4b7fb41086f 100644 --- a/inet/bits/inet-fortified.h +++ b/inet/bits/inet-fortified.h @@ -34,4 +34,21 @@ __NTH (inet_ntop (int __af, const void * __restrict __src, __af, __src, __dst, __dst_size); }; +__fortify_function int +__NTH (inet_pton (int __af, const char *__restrict __src, + void * __restrict __dst)) +{ + size_t sz = 0; + if (__af == AF_INET) + sz = sizeof (struct in_addr); + else if (__af == AF_INET6) + sz = sizeof (struct in6_addr); + else + return __inet_pton_alias (__af, __src, __dst); + + return __glibc_fortify (inet_pton, sz, sizeof (char), + __glibc_objsize (__dst), + __af, __src, __dst); +}; + #endif /* bits/inet-fortified.h. */ diff --git a/manual/maint.texi b/manual/maint.texi index ce6a556c68925b49..b6ee5b6e3bdf768c 100644 --- a/manual/maint.texi +++ b/manual/maint.texi @@ -305,6 +305,8 @@ The following functions and macros are fortified in @theglibc{}: @item @code{inet_ntop} +@item @code{inet_pton} + @item @code{longjmp} @item @code{mbsnrtowcs}