From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ot1-x329.google.com (mail-ot1-x329.google.com [IPv6:2607:f8b0:4864:20::329]) by sourceware.org (Postfix) with ESMTPS id B3D6E3858D32 for ; Mon, 29 May 2023 16:54:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B3D6E3858D32 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-ot1-x329.google.com with SMTP id 46e09a7af769-6af6f4a0e11so2629799a34.0 for ; Mon, 29 May 2023 09:54:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1685379272; x=1687971272; h=content-transfer-encoding:in-reply-to:organization:from:references :to:content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=3/+KfFjXPGB6+q2t3KSxLN2+87XG2HaZ+hzfMBXBSmM=; b=JD49VczuAsye4RB0qAFHnb/ZFRM9RsWbW/pPXgtE5mkcgex02a515grJQ8lZA93Oib e/V4aXwQSDXwsBW8ErkDhvIkfL8GhPCIN0A9H/HD3ApFBYtgtALvFv4yrCRZZFzMX5aq oHq359M9pYh4cqeRJhAjorvqkUTvNvNMTWjX4XTcwBSG9g+52ImnFt8wdNMkSjwnPIuU mm4tgqnJBB/0+PS+8LvYXK/667Dbf9HbkD/VpAMDCb5CgyPy5sA0mx9B3mwZpQtBzXS1 r9ESeRayPY0YGvqtf33nvo7i/qZK3WR+1KkD38UGv78YCPWlsGtsBXG+CLgMi73pfmqY riOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685379272; x=1687971272; h=content-transfer-encoding:in-reply-to:organization:from:references :to:content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3/+KfFjXPGB6+q2t3KSxLN2+87XG2HaZ+hzfMBXBSmM=; b=HKUHTo14YvVQdZ0lWE0+CDL4ppnM+STEW1C8abOTRvUz1TY2kNZoyasg9zgNlrQuvI fTRf6BxEEsRVNILL0AsBoTzs1S9t/1E2tSVGdM+eCxxfzSHwwG+UaoB054Lc/fLBJrA/ IyuNbTbhl4pFJPIkXNP4FqBHLXwZafzcwhEl15ZG7Lr7Ag24aSe8ABxkqVeB5Hr3lG6/ dD2nM1upKigRWIXwjgjEkVARiOE5dWnXIF85WhMIlCFKdS1z6qxhM9EVCjU6qGJ2ykBA k5ere4vllZexX7LT1Rj6oZnj0Chks1uYvroO3EHvASX2jFONGMhJqszEi5frLpVC9fYZ emWA== X-Gm-Message-State: AC+VfDwL/h2B3vXMT/nhEyJSdBabW1h1tF66gQkM2AFTJzEguk0x3Kst 2HfVIxgUxO1J8vzp9TaMnTP/Cr9cCQFLq87TS8Mtbg== X-Google-Smtp-Source: ACHHUZ4/7hF5RKRLlDwauk7VaBAAPSBm1lLxexTcLdFM42FigxzqulywKgfuTXtPeymaYeciqoyllQ== X-Received: by 2002:a9d:6c0d:0:b0:6af:8a79:12c8 with SMTP id f13-20020a9d6c0d000000b006af8a7912c8mr6173401otq.35.1685379271830; Mon, 29 May 2023 09:54:31 -0700 (PDT) Received: from ?IPV6:2804:1b3:a7c1:4dd5:7120:a40d:fc97:d6db? ([2804:1b3:a7c1:4dd5:7120:a40d:fc97:d6db]) by smtp.gmail.com with ESMTPSA id m6-20020a9d7e86000000b006addf2a4110sm4647643otp.55.2023.05.29.09.54.30 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 29 May 2023 09:54:31 -0700 (PDT) Message-ID: <31457dbb-a805-262f-4b62-be0b40960ca6@linaro.org> Date: Mon, 29 May 2023 13:54:28 -0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.11.1 Subject: Re: [PATCH v2 3/3] io: Add FORTIFY_SOURCE check for fcntl arguments Content-Language: en-US To: libc-alpha@sourceware.org, Sergey Bugaev References: <20230528172013.73111-1-bugaevc@gmail.com> <20230528172013.73111-4-bugaevc@gmail.com> From: Adhemerval Zanella Netto Organization: Linaro In-Reply-To: <20230528172013.73111-4-bugaevc@gmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 28/05/23 14:20, Sergey Bugaev via Libc-alpha wrote: > Both open () and fcntl () are "overloaded" to accept either 2 or 3 > arguments; whether the last argument is required (and, in case of fcntl, > the type of the third argument) depends on the values of the previous > arguments. Since C provides no native support for function overloading, > this is implemented by making these functions vararg. Unfortunately, > this means the compiler is unable to check the number of arguments and > their types for correctness at compile time, and will not diagnose any > mistakes. > > To help with this, when FORTIFY_SOURCE is enabled, the special fcntl2.h > header replaces open () with a wrapper that checks the passed number of > arguments, raising a compile-time or run-time error on mismatch. This > commit adds similar handling for fcntl (). > > Recently, Hector Martin has identified an issue in > libwebrtc where fcntl (fd, F_DUPFD_CLOEXEC) was invoked without a third > argument [0]. With the patch, the bug would have been detected at > compile time, assuming libwebrtc is built with FORTIFY_SOURCE. Hopefully > this will help detecting similar bugs in existing software, and prevent > more instances of similar bugs from being introduced in the future. > > [0]: https://social.treehouse.systems/@marcan/110355001391961285 > > Add tests for fcntl () and fcntl64 () calls still compiling and > functioning correctly in various configurations, and mention the new > fortification in the manual. > > The abilists have been modified with 'make update-abi-all'. Some comments below. > > Signed-off-by: Sergey Bugaev > --- > debug/tst-fortify.c | 148 +++++++ > include/fcntl.h | 1 + > io/Makefile | 1 + > io/Versions | 3 + > io/bits/fcntl2.h | 397 ++++++++++++++++++ > io/fcntl_2.c | 33 ++ > manual/maint.texi | 19 +- > sysdeps/mach/hurd/i386/libc.abilist | 1 + > sysdeps/mach/hurd/x86_64/libc.abilist | 1 + > sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + > sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + > sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + > sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + > sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + > sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + > sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + > sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + > sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + > .../sysv/linux/loongarch/lp64/libc.abilist | 1 + > .../sysv/linux/m68k/coldfire/libc.abilist | 1 + > .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + > .../sysv/linux/microblaze/be/libc.abilist | 1 + > .../sysv/linux/microblaze/le/libc.abilist | 1 + > .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + > .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + > .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + > .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + > sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + > sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + > .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + > .../powerpc/powerpc32/nofpu/libc.abilist | 1 + > .../linux/powerpc/powerpc64/be/libc.abilist | 1 + > .../linux/powerpc/powerpc64/le/libc.abilist | 1 + > .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + > .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + > .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + > .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + > sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + > sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + > .../sysv/linux/sparc/sparc32/libc.abilist | 1 + > .../sysv/linux/sparc/sparc64/libc.abilist | 1 + > .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + > .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + > 43 files changed, 632 insertions(+), 6 deletions(-) > create mode 100644 io/fcntl_2.c > > diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c > index 7850a4e5..03264154 100644 > --- a/debug/tst-fortify.c > +++ b/debug/tst-fortify.c > @@ -36,6 +36,8 @@ > #include > #include > #include > +#include > +#include > > #ifndef _GNU_SOURCE > # define MEMPCPY memcpy > @@ -78,6 +80,15 @@ do_prepare (void) > } > } > > +/* Return VALUE, but do it in a way that the compiler cannot > + see that it's a compile-time constant. */ > +static int __attribute_noinline__ > +hide_constant (int value) > +{ > + volatile int v = value; > + return v; > +} > + Interesting construct, but I wonder if 'volatile' is really required here. Afaiu what really prevents compiler to return fortify compiler warning here is the __attribute_noinline__. > volatile int chk_fail_ok; > volatile int ret; > jmp_buf chk_fail_buf; > @@ -1763,6 +1774,143 @@ do_test (void) > ppoll (fds, l0 + 2, NULL, NULL); > CHK_FAIL_END > # endif > +#endif > + > + /* Check that we can do basic fcntl operations, both ones that require > + the third argument, and ones that do not. */ > + res = fcntl (STDIN_FILENO, F_GETFD); > + TEST_COMPARE (res, 0); > + res = fcntl (STDIN_FILENO, F_SETFD, 0); > + TEST_COMPARE (res, 0); > + > +#ifdef F_OFD_GETLK > + /* Check for confusion between 32- and 64-bit versions of the fcntl > + interface. */ > + int lockfd1 = xopen (temp_filename, O_RDWR, 0); > + int lockfd2 = xopen (temp_filename, O_RDWR, 0); > + > + struct flock flock; Maybe move the flock struct to within the block for where ofd_locks_supported is true? > + int ofd_locks_supported = support_fcntl_support_ofd_locks (lockfd1); > + > + if (ofd_locks_supported) > + { > + memset (&flock, 0, sizeof (flock)); > + flock.l_type = F_WRLCK; > + flock.l_whence = SEEK_SET; > + flock.l_start = 1234; > + flock.l_len = 5678; > + flock.l_pid = 0; > + > + res = fcntl (lockfd1, F_OFD_SETLK, &flock); > + TEST_COMPARE (res, 0); > + > + memset (&flock, 0, sizeof (flock)); > + flock.l_type = F_RDLCK; > + flock.l_whence = SEEK_SET; > + flock.l_start = 3542; > + flock.l_len = 411; > + flock.l_pid = 0; > + > + res = fcntl (lockfd2, F_OFD_GETLK, &flock); > + TEST_COMPARE (res, 0); > + /* Check that we get the expected values. */ > + TEST_COMPARE (flock.l_type, F_WRLCK); > + TEST_COMPARE (flock.l_whence, SEEK_SET); > + TEST_COMPARE (flock.l_start, 1234); > + TEST_COMPARE (flock.l_len, 5678); > + TEST_COMPARE (flock.l_pid, -1); > + } > +#endif > + > + /* Check that we can do fcntl operations with CMD that is not constant > + at compile time. */ > + res = fcntl (STDIN_FILENO, hide_constant (F_GETFD)); > + TEST_COMPARE (res, 0); > + res = fcntl (STDIN_FILENO, hide_constant (F_SETFD), 0); > + TEST_COMPARE (res, 0); > + > +#ifdef F_OFD_GETLK > + if (ofd_locks_supported) > + { > + memset (&flock, 0, sizeof (flock)); > + flock.l_type = F_RDLCK; > + flock.l_whence = SEEK_SET; > + flock.l_start = 3542; > + flock.l_len = 411; > + flock.l_pid = 0; > + > + res = fcntl (lockfd2, hide_constant (F_OFD_GETLK), &flock); > + TEST_COMPARE (res, 0); > + /* Check that we get the expected values. */ > + TEST_COMPARE (flock.l_type, F_WRLCK); > + TEST_COMPARE (flock.l_whence, SEEK_SET); > + TEST_COMPARE (flock.l_start, 1234); > + TEST_COMPARE (flock.l_len, 5678); > + TEST_COMPARE (flock.l_pid, -1); > + } > +#endif > + > +#if __USE_FORTIFY_LEVEL >= 1 > + CHK_FAIL_START > + fcntl (STDIN_FILENO, hide_constant (F_SETFD)); > + CHK_FAIL_END > +#endif > + > +#if defined (__USE_LARGEFILE64) || defined (__USE_TIME_BITS64) There is no need to replicate the tests for the LFS support, this is already done by tst-fortify-cc-lfs-X tests. > + /* Also check fcntl64 (). */ > + res = fcntl64 (STDIN_FILENO, F_GETFD); > + TEST_COMPARE (res, 0); > + res = fcntl64 (STDIN_FILENO, F_SETFD, 0); > + TEST_COMPARE (res, 0); > + res = fcntl64 (STDIN_FILENO, hide_constant (F_GETFD)); > + TEST_COMPARE (res, 0); > + res = fcntl64 (STDIN_FILENO, hide_constant (F_SETFD), 0); > + TEST_COMPARE (res, 0); > + > +#ifdef F_OFD_GETLK > + if (ofd_locks_supported) > + { > + struct flock64 flock64; > + > + memset (&flock64, 0, sizeof (flock64)); > + flock64.l_type = F_RDLCK; > + flock64.l_whence = SEEK_SET; > + flock64.l_start = 3542; > + flock64.l_len = 411; > + flock64.l_pid = 0; > + > + res = fcntl64 (lockfd2, F_OFD_GETLK, &flock64); > + TEST_COMPARE (res, 0); > + /* Check that we get the expected values. */ > + TEST_COMPARE (flock64.l_type, F_WRLCK); > + TEST_COMPARE (flock64.l_whence, SEEK_SET); > + TEST_COMPARE (flock64.l_start, 1234); > + TEST_COMPARE (flock64.l_len, 5678); > + TEST_COMPARE (flock64.l_pid, -1); > + > + memset (&flock64, 0, sizeof (flock64)); > + flock64.l_type = F_RDLCK; > + flock64.l_whence = SEEK_SET; > + flock64.l_start = 3542; > + flock64.l_len = 411; > + flock64.l_pid = 0; > + > + res = fcntl64 (lockfd2, hide_constant (F_OFD_GETLK), &flock64); > + TEST_COMPARE (res, 0); > + /* Check that we get the expected values. */ > + TEST_COMPARE (flock64.l_type, F_WRLCK); > + TEST_COMPARE (flock64.l_whence, SEEK_SET); > + TEST_COMPARE (flock64.l_start, 1234); > + TEST_COMPARE (flock64.l_len, 5678); > + TEST_COMPARE (flock64.l_pid, -1); > + } > +#endif > + > +# if __USE_FORTIFY_LEVEL >= 1 > + CHK_FAIL_START > + fcntl64 (STDIN_FILENO, hide_constant (F_SETFD)); > + CHK_FAIL_END > +# endif > #endif > > return ret; > diff --git a/include/fcntl.h b/include/fcntl.h > index be435047..cb86c5e7 100644 > --- a/include/fcntl.h > +++ b/include/fcntl.h > @@ -32,6 +32,7 @@ extern int __open64_2 (const char *__path, int __oflag); > extern int __openat_2 (int __fd, const char *__path, int __oflag); > extern int __openat64_2 (int __fd, const char *__path, int __oflag); > > +extern int __fcntl_2 (int __fd, int __cmd); > > #if IS_IN (rtld) > # include > diff --git a/io/Makefile b/io/Makefile > index 6b58728e..1773a0f2 100644 > --- a/io/Makefile > +++ b/io/Makefile > @@ -71,6 +71,7 @@ routines := \ > fchownat \ > fcntl \ > fcntl64 \ > + fcntl_2 \ > file_change_detection \ > flock \ > fstat \ > diff --git a/io/Versions b/io/Versions > index 4e195408..0e77a287 100644 > --- a/io/Versions > +++ b/io/Versions > @@ -140,6 +140,9 @@ libc { > GLIBC_2.34 { > closefrom; > } > + GLIBC_2.38 { > + __fcntl_2; > + } > GLIBC_PRIVATE { > __libc_fcntl64; > __fcntl_nocancel; Ok. > diff --git a/io/bits/fcntl2.h b/io/bits/fcntl2.h > index bdb48fa8..e8dd3dea 100644 > --- a/io/bits/fcntl2.h > +++ b/io/bits/fcntl2.h > @@ -170,3 +170,400 @@ openat64 (int __fd, const char *__path, int __oflag, ...) > } > # endif > #endif > + > +extern int __fcntl_2 (int __fd, int __cmd); > + > +#ifndef __USE_TIME_BITS64 > + > +# ifndef __USE_FILE_OFFSET64 > +extern int __REDIRECT (__fcntl_alias, (int __fd, int __cmd, ...), fcntl); > +extern int __REDIRECT (__fcntl_warn, (int __fd, int __cmd, ...), fcntl) > + __warnattr ("fcntl argument has wrong type for this command"); > +# else > +extern int __REDIRECT (__fcntl_alias, (int __fd, int __cmd, ...), fcntl64); > +extern int __REDIRECT (__fcntl_warn, (int __fd, int __cmd, ...), fcntl64) > + __warnattr ("fcntl argument has wrong type for this command"); > +# endif /* __USE_FILE_OFFSET64 */ > + > +# ifdef __USE_LARGEFILE64 > +extern int __REDIRECT (__fcntl64_alias, (int __fd, int __cmd, ...), fcntl64); > +extern int __REDIRECT (__fcntl64_warn, (int __fd, int __cmd, ...), fcntl64) > + __warnattr ("fcntl64 argument has wrong type for this command"); > +# endif > + > +#else /* __USE_TIME_BITS64 */ > + > +extern int __REDIRECT_NTH (__fcntl_alias, (int __fd, int __cmd, ...), > + __fcntl_time64); > +extern int __REDIRECT_NTH (__fcntl64_alias, (int __fd, int __cmd, ...), > + __fcntl_time64); > +extern int __REDIRECT (__fcntl_warn, (int __fd, int __cmd, ...), > + __fcntl_time64) > + __warnattr ("fcntl argument has wrong type for this command"); > +extern int __REDIRECT (__fcntl64_warn, (int __fd, int __cmd, ...), > + __fcntl_time64) > + __warnattr ("fcntl64 argument has wrong type for this command"); > + > +#endif /* __USE_TIME_BITS64 */ > + > + > +/* Whether the fcntl CMD is known to require an argument. */ > +__extern_always_inline int > +__fcntl_requires_arg (int __cmd) > +{ > + switch (__cmd) > + { > + case F_DUPFD: > + case F_DUPFD_CLOEXEC: > + case F_SETFD: > + case F_SETFL: > +#ifdef F_SETLK > + case F_SETLK: > + case F_SETLKW: > + case F_GETLK: > +#endif > +#ifdef F_OFD_SETLK > + case F_OFD_SETLK: > + case F_OFD_SETLKW: > + case F_OFD_GETLK: > +#endif > +#ifdef F_SETOWN > + case F_SETOWN: > +#endif > +#ifdef F_GETOWN_EX > + case F_GETOWN_EX: > + case F_SETOWN_EX: > + case F_SETSIG: > +#endif > +#ifdef F_SETLEASE > + case F_SETLEASE: > + case F_NOTIFY: > + case F_SETPIPE_SZ: > + case F_ADD_SEALS: > + case F_GET_RW_HINT: > + case F_SET_RW_HINT: > + case F_GET_FILE_RW_HINT: > + case F_SET_FILE_RW_HINT: > +#endif > + return 1; > + > + default: > + return 0; > + } > +} > + > +/* Whether the fcntl CMD requires an int argument. */ > +__extern_always_inline int > +__fcntl_is_int (int __cmd) > +{ > + switch (__cmd) > + { > + case F_DUPFD: > + case F_DUPFD_CLOEXEC: > + case F_SETFD: > + case F_SETFL: > +#ifdef F_SETOWN > + case F_SETOWN: > +#endif > +#ifdef F_SETSIG > + case F_SETSIG: > +#endif > +#ifdef F_SETLEASE > + case F_SETLEASE: > + case F_NOTIFY: > + case F_SETPIPE_SZ: > + case F_ADD_SEALS: > +#endif > + return 1; > + > + default: > + return 0; > + } > +} > + > +/* Whether the fcntl CMD requires a (const uint64_t *) argument. */ > +__extern_always_inline int > +__fcntl_is_const_uint64_t_ptr (int __cmd) > +{ > + switch (__cmd) > + { > +#ifdef F_SET_RW_HINT > + case F_SET_RW_HINT: > + case F_SET_FILE_RW_HINT: > + return 1; > +#endif > + > + default: > + return 0; > + } > +} > + > + > +/* Whether the fcntl CMD requires an (uint64_t *) argument. */ > +__extern_always_inline int > +__fcntl_is_uint64_t_ptr (int __cmd) > +{ > + switch (__cmd) > + { > +#ifdef F_GET_RW_HINT > + case F_GET_RW_HINT: > + case F_GET_FILE_RW_HINT: > + return 1; > +#endif > + > + default: > + return 0; > + } > +} > + > +/* Whether the fcntl CMD requires a (const struct f_owner_ex *) argument. */ > +__extern_always_inline int > +__fcntl_is_const_fowner_ex (int __cmd) > +{ > + switch (__cmd) > + { > +#ifdef F_SETOWN_EX > + case F_SETOWN_EX: > + return 1; > +#endif > + > + default: > + return 0; > + } > +} > + > +/* Whether the fcntl CMD requires a (struct f_owner_ex *) argument. */ > +__extern_always_inline int > +__fcntl_is_fowner_ex (int __cmd) > +{ > + switch (__cmd) > + { > +#ifdef F_GETOWN_EX > + case F_GETOWN_EX: > + return 1; > +#endif > + > + default: > + return 0; > + } > +} > + > +/* Whether the fcntl CMD requires a (const struct flock *) argument. */ > +__extern_always_inline int > +__fcntl_is_const_flock (int __cmd, int __is_fcntl64) > +{ > + (void) __is_fcntl64; > + switch (__cmd) > + { > +#ifdef F_SETLK > + case F_SETLK: > + case F_SETLKW: > + return 1; > +#endif > + > +#ifdef F_OFD_SETLK > + case F_OFD_SETLK: > + case F_OFD_SETLKW: > + return !__is_fcntl64; > +#endif > + > + default: > + return 0; > + } > +} > + > +/* Whether the fcntl CMD requires a (struct flock *) argument. */ > +__extern_always_inline int > +__fcntl_is_flock (int __cmd, int __is_fcntl64) > +{ > + (void) __is_fcntl64; > + switch (__cmd) > + { > +#ifdef F_GETLK > + case F_GETLK: > + return 1; > +#endif > + > +#ifdef F_OFD_GETLK > + case F_OFD_GETLK: > + return !__is_fcntl64; > +#endif > + > + default: > + return 0; > + } > +} > + > +/* Whether the fcntl CMD requires a (const struct flock64 *) argument. */ > +__extern_always_inline int > +__fcntl_is_const_flock64 (int __cmd, int __is_fcntl64) > +{ > + (void) __is_fcntl64; > + switch (__cmd) > + { > +#ifdef F_SETLK64 > + case F_SETLK64: > + case F_SETLKW64: > + return 1; > +#endif > + > +#ifdef F_OFD_SETLK > + case F_OFD_SETLK: > + case F_OFD_SETLKW: > + return __is_fcntl64; > +#endif > + > + default: > + return 0; > + } > +} > + > +/* Whether the fcntl CMD requires a (struct flock64 *) argument. */ > +__extern_always_inline int > +__fcntl_is_flock64 (int __cmd, int __is_fcntl64) > +{ > + (void) __is_fcntl64; > + switch (__cmd) > + { > +#ifdef F_GETLK64 > + case F_GETLK64: > + return 1; > +#endif > + > +#ifdef F_OFD_GETLK > + case F_OFD_GETLK: > + return __is_fcntl64; > +#endif > + > + default: > + return 0; > + } > +} > + > +#ifndef __cplusplus > + > +# define __fcntl_types_compatible(arg, type) \ > + __builtin_types_compatible_p (__typeof (arg), type) > + > +#else > + > +template > +struct __fcntl_types_compatible_helper This makes the C++ tests fail with GCC 13: $ x86_64-glibc-linux-gnu-g++ [...] tst-fortify-cc-default-1-def.cc -D_FORTIFY_SOURCE=1 -Wno-format -Wno-deprecated-declarations -Wno-error [...] [...] In file included from ../include/bits/fcntl2.h:1, from ../io/fcntl.h:342, from ../include/fcntl.h:2, from ./tst-fortify.c:25, from /home/azanella/Projects/glibc/build/x86_64-linux-gnu/debug/tst-fortify-cc-default-1-def.cc:3: ../include/bits/../../io/bits/fcntl2.h:450:1: error: template with C linkage 450 | template | ^~~~~~~~ In file included from ../include/sys/cdefs.h:10, from ../include/features.h:503, from ./tst-fortify.c:20: ../misc/sys/cdefs.h:140:25: note: ‘extern "C"’ linkage started here 140 | # define __BEGIN_DECLS extern "C" { | ^~~~~~~~~~ ../io/fcntl.h:28:1: note: in expansion of macro ‘__BEGIN_DECLS’ 28 | __BEGIN_DECLS | ^~~~~~~~~~~~~ ../include/bits/../../io/bits/fcntl2.h:460:1: error: template with C linkage 460 | template | ^~~~~~~~ ../misc/sys/cdefs.h:140:25: note: ‘extern "C"’ linkage started here 140 | # define __BEGIN_DECLS extern "C" { | ^~~~~~~~~~ ../io/fcntl.h:28:1: note: in expansion of macro ‘__BEGIN_DECLS’ 28 | __BEGIN_DECLS | ^~~~~~~~~~~~~ In file included from ../misc/sys/select.h:30, from ../include/sys/select.h:2, from ../posix/sys/types.h:179, from ../include/sys/types.h:1, from ../stdlib/stdlib.h:514, from ../include/stdlib.h:16, from ./tst-fortify.c:31: [...] You will will need to include bits/fcntl2.h after the __END_DECLS, and add __BEGIN_DECLS/__END_DECLS on fcntl2.h. Something like this on top this patch: diff --git a/io/bits/fcntl2.h b/io/bits/fcntl2.h index e8dd3dea28..95323af2c2 100644 --- a/io/bits/fcntl2.h +++ b/io/bits/fcntl2.h @@ -20,6 +20,8 @@ # error "Never include directly; use instead." #endif +__BEGIN_DECLS + /* Check that calls to open and openat with O_CREAT or O_TMPFILE set have an appropriate third/fourth parameter. */ #ifndef __USE_FILE_OFFSET64 @@ -440,6 +442,8 @@ __fcntl_is_flock64 (int __cmd, int __is_fcntl64) } } +__END_DECLS + #ifndef __cplusplus # define __fcntl_types_compatible(arg, type) \ @@ -527,6 +531,7 @@ struct __fcntl_types_compatible_helper<__T, __T> __fcntl_is_flock64 (cmd, is_fcntl64) ? __fcntl_type_check_flock64 (arg) : \ 1) +__BEGIN_DECLS __errordecl (__fcntl_missing_arg, "fcntl with with this command needs 3 arguments"); @@ -567,3 +572,5 @@ __glibc_warn_system_headers_begin #endif __glibc_warn_system_headers_end + +__END_DECLS diff --git a/io/fcntl.h b/io/fcntl.h index dd620c086f..f6b6618424 100644 --- a/io/fcntl.h +++ b/io/fcntl.h @@ -335,6 +335,7 @@ extern int posix_fallocate64 (int __fd, off64_t __offset, off64_t __len); # endif #endif +__END_DECLS /* Define some inlines helping to catch common problems. */ #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function \ @@ -342,6 +343,4 @@ extern int posix_fallocate64 (int __fd, off64_t __offset, off64_t __len); # include #endif -__END_DECLS - #endif /* fcntl.h */ > +{ > + __always_inline static int > + __compatible () > + { > + return 0; > + } > +}; > + > +template > +struct __fcntl_types_compatible_helper<__T, __T> > +{ > + __always_inline static int > + __compatible () > + { > + return 1; > + } > +}; > + > +# define __fcntl_types_compatible(arg, type) \ > + __fcntl_types_compatible_helper<__typeof (arg), type>::__compatible () > + > +#endif /* __cplusplus */ > + > +#define __fcntl_type_check_int(arg) __fcntl_types_compatible (arg, int) > + > +#define __fcntl_type_check_const_uint64_t_ptr(arg) \ > + (__fcntl_types_compatible (arg, const __uint64_t *) \ > + || __fcntl_types_compatible (arg, __uint64_t *)) > + > +#define __fcntl_type_check_uint64_t_ptr(arg) \ > + __fcntl_types_compatible (arg, __uint64_t *) > + > +#define __fcntl_type_check_const_fowner_ex(arg) \ > + (__fcntl_types_compatible (arg, const struct f_owner_ex *) \ > + || __fcntl_types_compatible (arg, struct f_owner_ex *)) > + > +#define __fcntl_type_check_fowner_ex(arg) \ > + __fcntl_types_compatible (arg, struct f_owner_ex *) > + > +#define __fcntl_type_check_const_flock(arg) \ > + (__fcntl_types_compatible (arg, const struct flock *) \ > + || __fcntl_types_compatible (arg, struct flock *)) > + > +#define __fcntl_type_check_flock(arg) \ > + __fcntl_types_compatible (arg, struct flock *) > + > +#ifdef __USE_LARGEFILE64 > + > +# define __fcntl_type_check_const_flock64(arg) \ > + (__fcntl_types_compatible (arg, const struct flock64 *) \ > + || __fcntl_types_compatible (arg, struct flock64 *)) > + > +# define __fcntl_type_check_flock64(arg) \ > + __fcntl_types_compatible (arg, struct flock64 *) > + > +#else > + > +# define __fcntl_type_check_const_flock64(arg) 0 > +# define __fcntl_type_check_flock64(arg) 0 > + > +#endif /* __USE_LARGEFILE64 */ > + > +#define __fcntl_type_check(cmd, arg, is_fcntl64) \ > + (__fcntl_is_int (cmd) ? __fcntl_type_check_int (arg) : \ > + __fcntl_is_const_uint64_t_ptr (cmd) \ > + ? __fcntl_type_check_const_uint64_t_ptr (arg) : \ > + __fcntl_is_uint64_t_ptr (cmd) ? __fcntl_type_check_uint64_t_ptr (arg) : \ > + __fcntl_is_const_fowner_ex (cmd) \ > + ? __fcntl_type_check_const_fowner_ex (arg) : \ > + __fcntl_is_fowner_ex (cmd) ? __fcntl_type_check_fowner_ex (arg) : \ > + __fcntl_is_const_flock (cmd, is_fcntl64) \ > + ? __fcntl_type_check_const_flock (arg) : \ > + __fcntl_is_flock (cmd, is_fcntl64) ? __fcntl_type_check_flock (arg) : \ > + __fcntl_is_const_flock64 (cmd, is_fcntl64) \ > + ? __fcntl_type_check_const_flock64 (arg) : \ > + __fcntl_is_flock64 (cmd, is_fcntl64) ? __fcntl_type_check_flock64 (arg) : \ > + 1) > + > + > +__errordecl (__fcntl_missing_arg, > + "fcntl with with this command needs 3 arguments"); > + > +__fortify_function int > +__fcntl_2_inline (int __fd, int __cmd) > +{ > + if (!__builtin_constant_p (__cmd)) > + return __fcntl_2 (__fd, __cmd); > + > + if (__fcntl_requires_arg (__cmd)) > + __fcntl_missing_arg (); > + > + return __fcntl_alias (__fd, __cmd); > +} > + > +__glibc_warn_system_headers_begin > + > +#define fcntl(fd, cmd, ...) \ > + (__VA_OPT__ (0 ?) __fcntl_2_inline (fd, cmd) \ I think we will need to enable fcntl fortify only for gcc 8 or higher, since __VA_OPT__ is not support on gcc 7. > + __VA_OPT__ (: \ > + !__builtin_constant_p (cmd) ? __fcntl_alias (fd, cmd, __VA_ARGS__) \ > + : __fcntl_type_check (cmd, __VA_ARGS__, 0) \ > + ? __fcntl_alias (fd, cmd, __VA_ARGS__) \ > + : __fcntl_warn (fd, cmd, __VA_ARGS__))) > + > +#ifdef __USE_LARGEFILE64 > + > +#define fcntl64(fd, cmd, ...) \ > + (__VA_OPT__ (0 ?) __fcntl_2_inline (fd, cmd) \ > + __VA_OPT__ (: \ > + !__builtin_constant_p (cmd) ? __fcntl64_alias (fd, cmd, __VA_ARGS__) \ > + : __fcntl_type_check (cmd, __VA_ARGS__, 1) \ > + ? __fcntl64_alias (fd, cmd, __VA_ARGS__) \ > + : __fcntl64_warn (fd, cmd, __VA_ARGS__))) > + > + > +#endif > + > +__glibc_warn_system_headers_end > diff --git a/io/fcntl_2.c b/io/fcntl_2.c > new file mode 100644 > index 00000000..8db79c2a > --- /dev/null > +++ b/io/fcntl_2.c > @@ -0,0 +1,33 @@ > +/* _FORTIFY_SOURCE wrapper for fcntl. > + Copyright (C) 2013-2023 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 > + . */ > + > +/* Make sure to get __fcntl_requires_arg from bits/fcntl2.h */ > +#undef _FORTIFY_SOURCE > +#define _FORTIFY_SOURCE 1 > + > +#include > +#include > + > +int > +__fcntl_2 (int fd, int cmd) > +{ > + if (__fcntl_requires_arg (cmd)) > + __fortify_fail ("invalid fcntl call: this command requires an argument"); > + > + return __libc_fcntl64 (fd, cmd); > +} > diff --git a/manual/maint.texi b/manual/maint.texi > index a8441e20..74647e40 100644 > --- a/manual/maint.texi > +++ b/manual/maint.texi > @@ -200,7 +200,7 @@ functions but may also include checks for validity of other inputs to > the functions. > > When the @code{_FORTIFY_SOURCE} macro is defined, it enables code that > -validates inputs passed to some functions in @theglibc to determine if > +validates inputs passed to some functions in @theglibc{} to determine if > they are safe. If the compiler is unable to determine that the inputs > to the function call are safe, the call may be replaced by a call to its > hardened variant that does additional safety checks at runtime. Some > @@ -221,7 +221,8 @@ returned by the @code{__builtin_object_size} compiler builtin function. > If the function returns @code{(size_t) -1}, the function call is left > untouched. Additionally, this level also enables validation of flags to > the @code{open}, @code{open64}, @code{openat} and @code{openat64} > -functions. > +functions, as well as validation of the presence and the type of the > +third argument to the @code{fcntl} and @code{fcntl64} functions. > > @item @math{2}: This behaves like @math{1}, with the addition of some > checks that may trap code that is conforming but unsafe, e.g. accepting > @@ -243,10 +244,11 @@ depending on the architecture, one may also see fortified variants have > the @code{_chkieee128} suffix or the @code{__nldbl___} prefix to their > names. > > -Another exception is the @code{open} family of functions, where their > -fortified replacements have the @code{__} prefix and a @code{_2} suffix. > -The @code{FD_SET}, @code{FD_CLR} and @code{FD_ISSET} macros use the > -@code{__fdelt_chk} function on fortification. > +Another exception is the @code{open} and @code{fcntl} families of > +functions, where their fortified 2-argument version replacements have the > +@code{__} prefix and a @code{_2} suffix. The @code{FD_SET}, @code{FD_CLR} > +and @code{FD_ISSET} macros use the @code{__fdelt_chk} function on > +fortification. > > The following functions and macros are fortified in @theglibc{}: > @c Generated using the following command: > @@ -255,6 +257,7 @@ The following functions and macros are fortified in @theglibc{}: > @c sort -u | grep ^__ | > @c grep -v -e ieee128 -e __nldbl -e align_cpy -e "fdelt_warn" | > @c sed 's/__fdelt_chk/@item @code{FD_SET}\n\n@item @code{FD_CLR}\n\n@item @code{FD_ISSET}\n/' | > +@c sed 's/__fcntl_2/@item @code{fcntl}\n\n@item @code{fcntl64}\n/' | > @c sed 's/__\(.*\)_\(chk\|2\)/@item @code{\1}\n/' > > @itemize @bullet > @@ -267,6 +270,10 @@ The following functions and macros are fortified in @theglibc{}: > > @item @code{explicit_bzero} > > +@item @code{fcntl} > + > +@item @code{fcntl64} > + > @item @code{FD_SET} > > @item @code{FD_CLR} > diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist > index 6925222f..5397289b 100644 > --- a/sysdeps/mach/hurd/i386/libc.abilist > +++ b/sysdeps/mach/hurd/i386/libc.abilist > @@ -2294,6 +2294,7 @@ GLIBC_2.36 arc4random_buf F > GLIBC_2.36 arc4random_uniform F > GLIBC_2.36 c8rtomb F > GLIBC_2.36 mbrtoc8 F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/mach/hurd/x86_64/libc.abilist b/sysdeps/mach/hurd/x86_64/libc.abilist > index a0be5c1a..6ed14d1f 100644 > --- a/sysdeps/mach/hurd/x86_64/libc.abilist > +++ b/sysdeps/mach/hurd/x86_64/libc.abilist > @@ -194,6 +194,7 @@ GLIBC_2.38 __errno_location F > GLIBC_2.38 __explicit_bzero_chk F > GLIBC_2.38 __fbufsize F > GLIBC_2.38 __fcntl F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __fdelt_chk F > GLIBC_2.38 __fdelt_warn F > GLIBC_2.38 __fentry__ F > diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist > index 0e2d9c30..6a3e3e7c 100644 > --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist > @@ -2633,6 +2633,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist > index f1bec197..4cbc9346 100644 > --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist > +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist > @@ -2730,6 +2730,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist > index aa874b88..01fa7a34 100644 > --- a/sysdeps/unix/sysv/linux/arc/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist > @@ -2394,6 +2394,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > index afbd57da..2d7f5db4 100644 > --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > @@ -514,6 +514,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist > index e7364cd3..85eea0e5 100644 > --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist > @@ -511,6 +511,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist > index 913fa592..0bc57ae1 100644 > --- a/sysdeps/unix/sysv/linux/csky/libc.abilist > +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist > @@ -2670,6 +2670,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist > index 43af3a98..4f2e8b5d 100644 > --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist > +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist > @@ -2619,6 +2619,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist > index af72f8fa..8b8b8789 100644 > --- a/sysdeps/unix/sysv/linux/i386/libc.abilist > +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist > @@ -2803,6 +2803,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist > index 48cbb0fa..22f7f159 100644 > --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist > @@ -2568,6 +2568,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist > index c15884bb..acb9a793 100644 > --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist > @@ -2154,6 +2154,7 @@ GLIBC_2.36 wprintf F > GLIBC_2.36 write F > GLIBC_2.36 writev F > GLIBC_2.36 wscanf F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > index 3738db81..af6762d1 100644 > --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > @@ -515,6 +515,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > index ed136277..19ac2156 100644 > --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > @@ -2746,6 +2746,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > index 83577386..6d7e9d95 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > @@ -2719,6 +2719,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > index 58c5da58..08459ff7 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > @@ -2716,6 +2716,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > index d3741945..3b9caff0 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > @@ -2711,6 +2711,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > index 5319fdc2..2eb10c81 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > @@ -2709,6 +2709,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > index 1743ea6e..7f13cd56 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > @@ -2717,6 +2717,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > index 9b1f53c6..adea92bf 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > @@ -2619,6 +2619,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist > index ae1c6ca1..2816e0b3 100644 > --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist > +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist > @@ -2758,6 +2758,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist > index a7c572c9..93674747 100644 > --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist > +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist > @@ -2140,6 +2140,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > index 074fa031..68aa8601 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > @@ -2773,6 +2773,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > index dfcb4bd2..bc2f2b8d 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > @@ -2806,6 +2806,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > index 63bbccf3..cdc982a3 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > @@ -2527,6 +2527,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > index ab85fd61..66733662 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > @@ -2829,6 +2829,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fscanfieee128 F > GLIBC_2.38 __isoc23_fwscanf F > diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > index b716f5c7..6cf51998 100644 > --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > @@ -2396,6 +2396,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > index 774e777b..84f920f2 100644 > --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > @@ -2596,6 +2596,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > index 8625135c..c80822de 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > @@ -2771,6 +2771,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > index d00c7eb2..ac344828 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > @@ -2564,6 +2564,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > index b6303724..c064e000 100644 > --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > @@ -2626,6 +2626,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist > index d8005561..a185e3cb 100644 > --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist > @@ -2623,6 +2623,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > index 5be55c11..ad5aa083 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > @@ -2766,6 +2766,7 @@ GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > GLIBC_2.37 __ppoll64_chk F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > index 475fdaae..27fffe9d 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > @@ -2591,6 +2591,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > index 6cfb928b..3c46f003 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > @@ -2542,6 +2542,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F > diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > index c7350971..5a4fa94c 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > @@ -2648,6 +2648,7 @@ GLIBC_2.36 pidfd_open F > GLIBC_2.36 pidfd_send_signal F > GLIBC_2.36 process_madvise F > GLIBC_2.36 process_mrelease F > +GLIBC_2.38 __fcntl_2 F > GLIBC_2.38 __isoc23_fscanf F > GLIBC_2.38 __isoc23_fwscanf F > GLIBC_2.38 __isoc23_scanf F