public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Sergey Bugaev <bugaevc@gmail.com>
To: libc-alpha@sourceware.org
Subject: [PATCH v2 3/3] io: Add FORTIFY_SOURCE check for fcntl arguments
Date: Sun, 28 May 2023 20:20:13 +0300	[thread overview]
Message-ID: <20230528172013.73111-4-bugaevc@gmail.com> (raw)
In-Reply-To: <20230528172013.73111-1-bugaevc@gmail.com>

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 <marcan@marcan.st> 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'.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
---
 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 <sys/select.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <support/support.h>
+#include <support/xunistd.h>
 
 #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;
+}
+
 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;
+  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)
+  /* 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 <dl-fcntl.h>
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;
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<typename, typename>
+struct __fcntl_types_compatible_helper
+{
+  __always_inline static int
+  __compatible ()
+  {
+    return 0;
+  }
+};
+
+template<typename __T>
+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)				      \
+   __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
+   <https://www.gnu.org/licenses/>.  */
+
+/* Make sure to get __fcntl_requires_arg from bits/fcntl2.h */
+#undef _FORTIFY_SOURCE
+#define _FORTIFY_SOURCE 1
+
+#include <fcntl.h>
+#include <stdio.h>
+
+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
-- 
2.40.1


  parent reply	other threads:[~2023-05-28 17:20 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-28 17:20 [PATCH v2 0/3] fcntl fortification Sergey Bugaev
2023-05-28 17:20 ` [PATCH v2 1/3] support: Add support_fcntl_support_ofd_locks () Sergey Bugaev
2023-05-29 13:18   ` Adhemerval Zanella Netto
2023-05-28 17:20 ` [PATCH v2 2/3] cdefs.h: Define __glibc_warn_system_headers_{begin,end} Sergey Bugaev
2023-05-29 14:50   ` [PATCH v2 2/3] cdefs.h: Define __glibc_warn_system_headers_{begin, end} Adhemerval Zanella Netto
2023-05-28 17:20 ` Sergey Bugaev [this message]
2023-05-29 16:54   ` [PATCH v2 3/3] io: Add FORTIFY_SOURCE check for fcntl arguments Adhemerval Zanella Netto
2023-05-29 17:31     ` Sergey Bugaev
2023-05-29 18:09       ` Adhemerval Zanella Netto
2023-05-29 19:57         ` Sergey Bugaev
2023-05-29 20:14           ` Adhemerval Zanella Netto
2023-05-29 20:49             ` Sergey Bugaev
2023-05-29 21:09               ` Adhemerval Zanella Netto
2023-05-29 21:59                 ` Sergey Bugaev
2023-05-30 11:34                   ` Adhemerval Zanella Netto
2023-05-30  7:41         ` Florian Weimer
2023-05-30  9:07           ` Sergey Bugaev
2023-05-30  9:50             ` Florian Weimer
2023-05-30 11:35               ` Adhemerval Zanella Netto
2023-05-30  8:09 ` [PATCH v2 0/3] fcntl fortification Florian Weimer
2023-05-30 10:46   ` Sergey Bugaev
2023-05-30 11:08     ` Florian Weimer
2023-05-30 11:34       ` Sergey Bugaev
2023-05-30 11:50         ` Florian Weimer
2023-05-30 11:51         ` Florian Weimer
2023-05-30 12:15           ` Sergey Bugaev
2023-05-30 12:26             ` Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230528172013.73111-4-bugaevc@gmail.com \
    --to=bugaevc@gmail.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).