@@ -1901,6 +1901,12 @@ do_test (void)
}
#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);
@@ -1951,6 +1957,11 @@ do_test (void)
}
#endif
+# if __USE_FORTIFY_LEVEL >= 1
+ CHK_FAIL_START
+ fcntl64 (STDIN_FILENO, hide_constant (F_SETFD));
+ CHK_FAIL_END
+# endif
#endif
return ret;
@@ -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>
@@ -72,6 +72,7 @@ routines := \
fchownat \
fcntl \
fcntl64 \
+ fcntl_2 \
file_change_detection \
flock \
fstat \
@@ -140,6 +140,9 @@ libc {
GLIBC_2.34 {
closefrom;
}
+ GLIBC_2.38 {
+ __fcntl_2;
+ }
GLIBC_PRIVATE {
__libc_fcntl64;
__fcntl_nocancel;
@@ -20,6 +20,8 @@
# error "Never include <bits/fcntl3.h> directly; use <fcntl.h> instead."
#endif
+extern int __fcntl_2 (int __fd, int __cmd);
+
#ifndef __USE_TIME_BITS64
# ifndef __USE_FILE_OFFSET64
@@ -386,7 +388,7 @@ __fortify_function int
__fcntl_2_inline (int __fd, int __cmd)
{
if (!__builtin_constant_p (__cmd))
- return __fcntl_alias (__fd, __cmd);
+ return __fcntl_2 (__fd, __cmd);
if (__fcntl_requires_arg (__cmd))
__fcntl_missing_arg ();
new file mode 100644
@@ -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/fcntl3.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 cmd requires an argument");
+
+ return __libc_fcntl64 (fd, cmd);
+}
@@ -244,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:
@@ -256,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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
This adds a runtime fortification function, __fcntl_2, similar to __open_2, that checks at runtime whether the actual passed-in command in fact requires a third argument, and aborts if so. The abilists have been modified with 'make update-abi-all'. Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> --- debug/tst-fortify.c | 11 +++++++ include/fcntl.h | 1 + io/Makefile | 1 + io/Versions | 3 ++ io/bits/fcntl3.h | 4 ++- io/fcntl_2.c | 33 +++++++++++++++++++ manual/maint.texi | 10 +++--- 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, 94 insertions(+), 5 deletions(-) create mode 100644 io/fcntl_2.c