Message ID | 20230519213059.3812385-2-bugaevc@gmail.com |
---|---|
State | New |
Headers | show |
Series | Attempt to detect missing fcntl argument at compile time | expand |
I'm concerned about the lack of testcases in this patch. I'm not sure of how we should be checking for compile-time errors (there are several existing tests for runtime fortification), but having this functionality without testcases seems risky.
Hello, On Sat, May 20, 2023 at 12:55 AM Joseph Myers <joseph@codesourcery.com> wrote: > I'm concerned about the lack of testcases in this patch. I'm not sure of > how we should be checking for compile-time errors (there are several > existing tests for runtime fortification), but having this functionality > without testcases seems risky. Yes, absolutely, I agree. Let me attempt to add some tests then! Considering it's unclear how to test for compilation errors, maybe we don't have to (despite these errors being the main point of the patch). What's important is ensuring that the fortification doesn't break legitimate programs, either because of me messing up how fcntl/fcntl64 are defined in some particular configuration vs how they are now defined in fcntl2.h, or because of some undefined F_COMMAND being used in __fcntl_cmd_needs_arg. I see that there's already debug/tst-fortify.c that gets built and tested in various configurations (exactly what I need!) and even has the CHK_FAIL_START / CHK_FAIL_END facilities for catching the SIGABRT and recording test success. So should I just add a bunch of fcntl/fcntl64 tests there? What would be a good way to test for 32-bit vs 64-bit confusion? Something involving F_OFD_*LK, perhaps? Is there an existing test for open{at,64,at64} fortification somewhere that I could copy-paste^W^W take inspiration from? Sergey
On 19/05/23 18:30, 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 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 > > The abilists have been modified with 'make update-abi-all'. > > Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> > --- > include/fcntl.h | 3 + > io/Makefile | 2 +- > io/Versions | 4 + > io/bits/fcntl2.h | 139 ++++++++++++++++++ > io/fcntl64_2.c | 33 +++++ > io/fcntl_2.c | 33 +++++ > sysdeps/mach/hurd/i386/libc.abilist | 2 + > sysdeps/mach/hurd/x86_64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 + > sysdeps/unix/sysv/linux/arc/libc.abilist | 2 + > sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 + > sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 + > sysdeps/unix/sysv/linux/csky/libc.abilist | 2 + > sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 + > sysdeps/unix/sysv/linux/i386/libc.abilist | 2 + > sysdeps/unix/sysv/linux/ia64/libc.abilist | 2 + > .../sysv/linux/loongarch/lp64/libc.abilist | 2 + > .../sysv/linux/m68k/coldfire/libc.abilist | 2 + > .../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 + > .../sysv/linux/microblaze/be/libc.abilist | 2 + > .../sysv/linux/microblaze/le/libc.abilist | 2 + > .../sysv/linux/mips/mips32/fpu/libc.abilist | 2 + > .../sysv/linux/mips/mips32/nofpu/libc.abilist | 2 + > .../sysv/linux/mips/mips64/n32/libc.abilist | 2 + > .../sysv/linux/mips/mips64/n64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 + > sysdeps/unix/sysv/linux/or1k/libc.abilist | 2 + > .../linux/powerpc/powerpc32/fpu/libc.abilist | 2 + > .../powerpc/powerpc32/nofpu/libc.abilist | 2 + > .../linux/powerpc/powerpc64/be/libc.abilist | 2 + > .../linux/powerpc/powerpc64/le/libc.abilist | 2 + > .../unix/sysv/linux/riscv/rv32/libc.abilist | 2 + > .../unix/sysv/linux/riscv/rv64/libc.abilist | 2 + > .../unix/sysv/linux/s390/s390-32/libc.abilist | 2 + > .../unix/sysv/linux/s390/s390-64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 + > sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 + > .../sysv/linux/sparc/sparc32/libc.abilist | 2 + > .../sysv/linux/sparc/sparc64/libc.abilist | 2 + > .../unix/sysv/linux/x86_64/64/libc.abilist | 2 + > .../unix/sysv/linux/x86_64/x32/libc.abilist | 2 + > 42 files changed, 285 insertions(+), 1 deletion(-) > create mode 100644 io/fcntl64_2.c > create mode 100644 io/fcntl_2.c > > diff --git a/include/fcntl.h b/include/fcntl.h > index d788db2e..7742c002 100644 > --- a/include/fcntl.h > +++ b/include/fcntl.h > @@ -32,6 +32,9 @@ 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); > +extern int __fcntl64_2 (int __fd, int __cmd); > + > > /* Makes open () & friends faster on the Hurd, but can only be used (without > altering user-visible behavior) when we're sure that the file we're opening > diff --git a/io/Makefile b/io/Makefile > index f72571cd..350807ee 100644 > --- a/io/Makefile > +++ b/io/Makefile > @@ -41,7 +41,7 @@ routines := \ > mkdir mkdirat \ > open open_2 open64 open64_2 openat openat_2 openat64 openat64_2 \ > read write lseek lseek64 access euidaccess faccessat \ > - fcntl fcntl64 flock lockf lockf64 \ > + fcntl fcntl_2 fcntl64 fcntl64_2 flock lockf lockf64 \ > close dup dup2 dup3 pipe pipe2 \ > creat creat64 \ > chdir fchdir \ > diff --git a/io/Versions b/io/Versions > index 4e195408..8409e105 100644 > --- a/io/Versions > +++ b/io/Versions > @@ -140,6 +140,10 @@ libc { > GLIBC_2.34 { > closefrom; > } > + GLIBC_2.38 { > + __fcntl_2; > + __fcntl64_2; > + } > GLIBC_PRIVATE { > __libc_fcntl64; > __fcntl_nocancel; > diff --git a/io/bits/fcntl2.h b/io/bits/fcntl2.h > index bdb48fa8..beb3a628 100644 > --- a/io/bits/fcntl2.h > +++ b/io/bits/fcntl2.h > @@ -170,3 +170,142 @@ openat64 (int __fd, const char *__path, int __oflag, ...) > } > # endif > #endif > + > +#ifndef __USE_TIME_BITS64 > + > +# ifndef __USE_FILE_OFFSET64 > +/* Just fcntl (). */ Does this comment adds anything? Also I think we avoid to use '()' on function definition on comments. > +extern int __fcntl_2 (int __fd, int __cmd); > +extern int __REDIRECT (__fcntl_alias, (int __fd, int __cmd, ...), fcntl); > +# else > +/* fcntl.h redirects fcntl () to fcntl64 (). */ > +extern int __REDIRECT (__fcntl_2, (int __fd, int __cmd), __fcntl64_2); > +extern int __REDIRECT (__fcntl_alias, (int __fd, int __cmd, ...), fcntl64); > +# endif /* __USE_FILE_OFFSET64 */ > + > +# ifdef __USE_LARGEFILE64 > +/* Just fcntl64 (). */ > +extern int __fcntl64_2 (int __fd, int __cmd); > +extern int __REDIRECT (__fcntl64_alias, (int __fd, int __cmd, ...), fcntl64); > +# endif > + > +#else /* __USE_TIME_BITS64 */ > + > +/* fcntl.h redirects both fcntl () and fcntl64 () to __fcntl_time64 (). */ > +extern int __fcntl64_2 (int __fd, int __cmd); > +extern int __REDIRECT (__fcntl_2, (int __fd, int __cmd), __fcntl64_2); > +extern int __REDIRECT_NTH (__fcntl_alias, (int __fd, int __cmd, ...), > + __fcntl_time64); > +extern int __REDIRECT_NTH (__fcntl64_alias, (int __fd, int __cmd, ...), > + __fcntl_time64); > +#endif /* __USE_TIME_BITS64 */ > + > +__errordecl (__fcntl_too_many_args, > + "fcntl can be called either with 2 or 3 arguments, not more"); > +__errordecl (__fcntl_missing_arg, > + "fcntl with with this cmd needs 3 arguments"); > + > +__extern_always_inline int Should we use __fortify_function also for this case? > +__fcntl_cmd_needs_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 I think it would be better to condicionalize using __USE_GNU: #ifdef __USE_GNU case F_GETOWN_EX: case F_SETOWN_EX: case F_SETSIG: #endif Since the double underscore symbols are implementation defined one and should not be used by the application. > +#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; > + > + case F_GETFD: > + case F_GETFL: > +#ifdef F_GETOWN > + case F_GETOWN: > +#endif > +#ifdef __F_GETSIG > + case __F_GETSIG: > +#endif > +#ifdef F_GETLEASE > + case F_GETLEASE: > + case F_GETPIPE_SZ: > + case F_GET_SEALS: > +#endif > + /* For any cmd value we don't know about, > + default to not requiring an argument. */ > + default: > + return 0; > + } > +} Should be worried that since we don't have const expressions like newer C++ that large switch might ended being extra code on every fcntl call? I think the __builtin_constant_p check below gives compiler enough information to avoid it, but I am not sure. > + > +__fortify_function int > +fcntl (int __fd, int __cmd, ...) > +{ > + if (__va_arg_pack_len () > 1) > + __fcntl_too_many_args (); > + > + if (__builtin_constant_p (__cmd)) > + { > + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) No implicit check for function that do not return bool: if (__fcntl_cmd_needs_arg (__cmd) == 1 ...) > + { > + __fcntl_missing_arg (); > + return __fcntl_2 (__fd, __cmd); > + } > + return __fcntl_alias (__fd, __cmd, __va_arg_pack ()); > + } > + > + if (__va_arg_pack_len () < 1) > + return __fcntl_2 (__fd, __cmd); > + > + return __fcntl_alias (__fd, __cmd, __va_arg_pack ()); > +} > + > +#ifdef __USE_LARGEFILE64 > +__fortify_function int > +fcntl64 (int __fd, int __cmd, ...) > +{ > + if (__va_arg_pack_len () > 1) > + __fcntl_too_many_args (); > + > + if (__builtin_constant_p (__cmd)) > + { > + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) > + { > + __fcntl_missing_arg (); > + return __fcntl64_2 (__fd, __cmd); > + } > + return __fcntl64_alias (__fd, __cmd, __va_arg_pack ()); > + } > + > + if (__va_arg_pack_len () < 1) > + return __fcntl64_2 (__fd, __cmd); > + > + return __fcntl64_alias (__fd, __cmd, __va_arg_pack ()); > +} > +#endif I think we need also to handle __USE_TIME_BITS64 and add another fcntl debug symbol to handle; even though for Linux now __fcntl_time64 is just a alias to __libc_fcntl64. It is because we even need to add a proper __fcntl_time64 implementation, the redirection now does: fcntl -> __fcntl64_2 -> __libc_fcntl64 Where it should be something like: fcntl -> __fcntl_time64_2 -> __fcntl_time64 > diff --git a/io/fcntl64_2.c b/io/fcntl64_2.c > new file mode 100644 > index 00000000..6352f524 > --- /dev/null > +++ b/io/fcntl64_2.c > @@ -0,0 +1,33 @@ > +/* _FORTIFY_SOURCE wrapper for fcntl64. > + 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_cmd_needs_arg from bits/fcntl2.h */ > +#undef _FORTIFY_SOURCE > +#define _FORTIFY_SOURCE 1 > + > +#include <fcntl.h> > +#include <stdio.h> > + > +int > +__fcntl64_2 (int fd, int cmd) > +{ > + if (__fcntl_cmd_needs_arg (cmd)) > + __fortify_fail ("invalid fcntl64 call: this cmd requires an argument"); > + > + return __libc_fcntl64 (fd, cmd); > +} Ok. > diff --git a/io/fcntl_2.c b/io/fcntl_2.c > new file mode 100644 > index 00000000..fc9303e4 > --- /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_cmd_needs_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_cmd_needs_arg (cmd)) > + __fortify_fail ("invalid fcntl call: this cmd requires an argument"); > + > + return __libc_fcntl (fd, cmd); > +} Ok. > diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist > index 6925222f..fa24d577 100644 > --- a/sysdeps/mach/hurd/i386/libc.abilist > +++ b/sysdeps/mach/hurd/i386/libc.abilist > @@ -2294,6 +2294,8 @@ 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 __fcntl64_2 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..efb83b16 100644 > --- a/sysdeps/mach/hurd/x86_64/libc.abilist > +++ b/sysdeps/mach/hurd/x86_64/libc.abilist > @@ -194,6 +194,8 @@ 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 __fcntl64_2 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..86144979 100644 > --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist > @@ -2633,6 +2633,8 @@ 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 __fcntl64_2 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..646c11e3 100644 > --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist > +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist > @@ -2730,6 +2730,8 @@ 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 __fcntl64_2 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..37e9129f 100644 > --- a/sysdeps/unix/sysv/linux/arc/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist > @@ -2394,6 +2394,8 @@ 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 __fcntl64_2 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..4c9b937e 100644 > --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > @@ -514,6 +514,8 @@ 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 __fcntl64_2 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..8dbf72c5 100644 > --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist > @@ -511,6 +511,8 @@ 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 __fcntl64_2 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..b58b2b9c 100644 > --- a/sysdeps/unix/sysv/linux/csky/libc.abilist > +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist > @@ -2670,6 +2670,8 @@ 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 __fcntl64_2 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..c80bb835 100644 > --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist > +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist > @@ -2619,6 +2619,8 @@ 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 __fcntl64_2 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..5a737b3d 100644 > --- a/sysdeps/unix/sysv/linux/i386/libc.abilist > +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist > @@ -2803,6 +2803,8 @@ 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 __fcntl64_2 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..aab6d422 100644 > --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist > @@ -2568,6 +2568,8 @@ 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 __fcntl64_2 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..82da98d2 100644 > --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist > @@ -2154,6 +2154,8 @@ GLIBC_2.36 wprintf F > GLIBC_2.36 write F > GLIBC_2.36 writev F > GLIBC_2.36 wscanf F > +GLIBC_2.38 __fcntl64_2 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..f6c80b46 100644 > --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > @@ -515,6 +515,8 @@ 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 __fcntl64_2 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..dc34ea56 100644 > --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > @@ -2746,6 +2746,8 @@ 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 __fcntl64_2 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..466e4092 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > @@ -2719,6 +2719,8 @@ 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 __fcntl64_2 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..dc27b4e7 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > @@ -2716,6 +2716,8 @@ 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 __fcntl64_2 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..a8dfa647 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > @@ -2711,6 +2711,8 @@ 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 __fcntl64_2 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..4defd8dc 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > @@ -2709,6 +2709,8 @@ 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 __fcntl64_2 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..824b6b4c 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > @@ -2717,6 +2717,8 @@ 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 __fcntl64_2 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..ff4341a8 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > @@ -2619,6 +2619,8 @@ 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 __fcntl64_2 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..ede0e6eb 100644 > --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist > +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist > @@ -2758,6 +2758,8 @@ 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 __fcntl64_2 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..22525fe8 100644 > --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist > +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist > @@ -2140,6 +2140,8 @@ 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 __fcntl64_2 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..2938361e 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > @@ -2773,6 +2773,8 @@ 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 __fcntl64_2 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..e1c70a25 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > @@ -2806,6 +2806,8 @@ 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 __fcntl64_2 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..2ce2d974 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > @@ -2527,6 +2527,8 @@ 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 __fcntl64_2 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..b1024501 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > @@ -2829,6 +2829,8 @@ 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 __fcntl64_2 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..833fb747 100644 > --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > @@ -2396,6 +2396,8 @@ 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 __fcntl64_2 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..cbd85454 100644 > --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > @@ -2596,6 +2596,8 @@ 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 __fcntl64_2 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..1442a0b9 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > @@ -2771,6 +2771,8 @@ 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 __fcntl64_2 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..1a7f4fc7 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > @@ -2564,6 +2564,8 @@ 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 __fcntl64_2 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..3146ce99 100644 > --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > @@ -2626,6 +2626,8 @@ 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 __fcntl64_2 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..31360691 100644 > --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist > @@ -2623,6 +2623,8 @@ 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 __fcntl64_2 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..026e9581 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > @@ -2766,6 +2766,8 @@ 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 __fcntl64_2 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..6ecb0d46 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > @@ -2591,6 +2591,8 @@ 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 __fcntl64_2 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..a37f4ab4 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > @@ -2542,6 +2542,8 @@ 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 __fcntl64_2 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..3b8790f4 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > @@ -2648,6 +2648,8 @@ 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 __fcntl64_2 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
On 2023-05-19 17:30, 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 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 > > The abilists have been modified with 'make update-abi-all'. > > Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> > --- > include/fcntl.h | 3 + > io/Makefile | 2 +- > io/Versions | 4 + > io/bits/fcntl2.h | 139 ++++++++++++++++++ > io/fcntl64_2.c | 33 +++++ > io/fcntl_2.c | 33 +++++ > sysdeps/mach/hurd/i386/libc.abilist | 2 + > sysdeps/mach/hurd/x86_64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 + > sysdeps/unix/sysv/linux/arc/libc.abilist | 2 + > sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 + > sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 + > sysdeps/unix/sysv/linux/csky/libc.abilist | 2 + > sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 + > sysdeps/unix/sysv/linux/i386/libc.abilist | 2 + > sysdeps/unix/sysv/linux/ia64/libc.abilist | 2 + > .../sysv/linux/loongarch/lp64/libc.abilist | 2 + > .../sysv/linux/m68k/coldfire/libc.abilist | 2 + > .../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 + > .../sysv/linux/microblaze/be/libc.abilist | 2 + > .../sysv/linux/microblaze/le/libc.abilist | 2 + > .../sysv/linux/mips/mips32/fpu/libc.abilist | 2 + > .../sysv/linux/mips/mips32/nofpu/libc.abilist | 2 + > .../sysv/linux/mips/mips64/n32/libc.abilist | 2 + > .../sysv/linux/mips/mips64/n64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 + > sysdeps/unix/sysv/linux/or1k/libc.abilist | 2 + > .../linux/powerpc/powerpc32/fpu/libc.abilist | 2 + > .../powerpc/powerpc32/nofpu/libc.abilist | 2 + > .../linux/powerpc/powerpc64/be/libc.abilist | 2 + > .../linux/powerpc/powerpc64/le/libc.abilist | 2 + > .../unix/sysv/linux/riscv/rv32/libc.abilist | 2 + > .../unix/sysv/linux/riscv/rv64/libc.abilist | 2 + > .../unix/sysv/linux/s390/s390-32/libc.abilist | 2 + > .../unix/sysv/linux/s390/s390-64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 + > sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 + > .../sysv/linux/sparc/sparc32/libc.abilist | 2 + > .../sysv/linux/sparc/sparc64/libc.abilist | 2 + > .../unix/sysv/linux/x86_64/64/libc.abilist | 2 + > .../unix/sysv/linux/x86_64/x32/libc.abilist | 2 + > 42 files changed, 285 insertions(+), 1 deletion(-) > create mode 100644 io/fcntl64_2.c > create mode 100644 io/fcntl_2.c > > diff --git a/include/fcntl.h b/include/fcntl.h > index d788db2e..7742c002 100644 > --- a/include/fcntl.h > +++ b/include/fcntl.h > @@ -32,6 +32,9 @@ 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); > +extern int __fcntl64_2 (int __fd, int __cmd); > + With my Bikeshed Aesthetics Consultant hat on, the naming of fortified variants of file ops functions as *_2 is awkward, they should have been *_chk but I don't want to block this good work on that. The overall direction is good IMO (and I see Adhemerval is on it with a deeper review), just some notes: - manual/contrib.texi should be updated to mention fcntl - Internal users end up calling __libc_fcntl (see dup2.c or grantpt.c for example), which will essentially bypass any fortification. This is not a problem today since we don't build glibc with fortification, but Frederic Berat[1] has been experimenting with that and we're hoping to get at least a subset of glibc fortified for 2.38. It would be a shame to miss fortifying glibc itself. This is again not a problem that would block this patch, but something to be aware of. > > /* Makes open () & friends faster on the Hurd, but can only be used (without > altering user-visible behavior) when we're sure that the file we're opening > diff --git a/io/Makefile b/io/Makefile > index f72571cd..350807ee 100644 > --- a/io/Makefile > +++ b/io/Makefile > @@ -41,7 +41,7 @@ routines := \ > mkdir mkdirat \ > open open_2 open64 open64_2 openat openat_2 openat64 openat64_2 \ > read write lseek lseek64 access euidaccess faccessat \ > - fcntl fcntl64 flock lockf lockf64 \ > + fcntl fcntl_2 fcntl64 fcntl64_2 flock lockf lockf64 \ > close dup dup2 dup3 pipe pipe2 \ > creat creat64 \ > chdir fchdir \ > diff --git a/io/Versions b/io/Versions > index 4e195408..8409e105 100644 > --- a/io/Versions > +++ b/io/Versions > @@ -140,6 +140,10 @@ libc { > GLIBC_2.34 { > closefrom; > } > + GLIBC_2.38 { > + __fcntl_2; > + __fcntl64_2; > + } > GLIBC_PRIVATE { > __libc_fcntl64; > __fcntl_nocancel; > diff --git a/io/bits/fcntl2.h b/io/bits/fcntl2.h > index bdb48fa8..beb3a628 100644 > --- a/io/bits/fcntl2.h > +++ b/io/bits/fcntl2.h > @@ -170,3 +170,142 @@ openat64 (int __fd, const char *__path, int __oflag, ...) > } > # endif > #endif > + > +#ifndef __USE_TIME_BITS64 > + > +# ifndef __USE_FILE_OFFSET64 > +/* Just fcntl (). */ > +extern int __fcntl_2 (int __fd, int __cmd); > +extern int __REDIRECT (__fcntl_alias, (int __fd, int __cmd, ...), fcntl); > +# else > +/* fcntl.h redirects fcntl () to fcntl64 (). */ > +extern int __REDIRECT (__fcntl_2, (int __fd, int __cmd), __fcntl64_2); > +extern int __REDIRECT (__fcntl_alias, (int __fd, int __cmd, ...), fcntl64); > +# endif /* __USE_FILE_OFFSET64 */ > + > +# ifdef __USE_LARGEFILE64 > +/* Just fcntl64 (). */ > +extern int __fcntl64_2 (int __fd, int __cmd); > +extern int __REDIRECT (__fcntl64_alias, (int __fd, int __cmd, ...), fcntl64); > +# endif > + > +#else /* __USE_TIME_BITS64 */ > + > +/* fcntl.h redirects both fcntl () and fcntl64 () to __fcntl_time64 (). */ > +extern int __fcntl64_2 (int __fd, int __cmd); > +extern int __REDIRECT (__fcntl_2, (int __fd, int __cmd), __fcntl64_2); > +extern int __REDIRECT_NTH (__fcntl_alias, (int __fd, int __cmd, ...), > + __fcntl_time64); > +extern int __REDIRECT_NTH (__fcntl64_alias, (int __fd, int __cmd, ...), > + __fcntl_time64); > +#endif /* __USE_TIME_BITS64 */ > + > +__errordecl (__fcntl_too_many_args, > + "fcntl can be called either with 2 or 3 arguments, not more"); > +__errordecl (__fcntl_missing_arg, > + "fcntl with with this cmd needs 3 arguments"); > + > +__extern_always_inline int > +__fcntl_cmd_needs_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; > + > + case F_GETFD: > + case F_GETFL: > +#ifdef F_GETOWN > + case F_GETOWN: > +#endif > +#ifdef __F_GETSIG > + case __F_GETSIG: > +#endif > +#ifdef F_GETLEASE > + case F_GETLEASE: > + case F_GETPIPE_SZ: > + case F_GET_SEALS: > +#endif > + /* For any cmd value we don't know about, > + default to not requiring an argument. */ > + default: > + return 0; > + } > +} > + > +__fortify_function int > +fcntl (int __fd, int __cmd, ...) > +{ > + if (__va_arg_pack_len () > 1) > + __fcntl_too_many_args (); > + > + if (__builtin_constant_p (__cmd)) > + { > + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) > + { > + __fcntl_missing_arg (); > + return __fcntl_2 (__fd, __cmd); > + } > + return __fcntl_alias (__fd, __cmd, __va_arg_pack ()); > + } > + > + if (__va_arg_pack_len () < 1) > + return __fcntl_2 (__fd, __cmd); > + > + return __fcntl_alias (__fd, __cmd, __va_arg_pack ()); > +} > + > +#ifdef __USE_LARGEFILE64 > +__fortify_function int > +fcntl64 (int __fd, int __cmd, ...) > +{ > + if (__va_arg_pack_len () > 1) > + __fcntl_too_many_args (); > + > + if (__builtin_constant_p (__cmd)) > + { > + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) > + { > + __fcntl_missing_arg (); Given that this will error out at compile time, do we even need this __fcntl64_2 call? > + return __fcntl64_2 (__fd, __cmd); > + } > + return __fcntl64_alias (__fd, __cmd, __va_arg_pack ()); > + } > + > + if (__va_arg_pack_len () < 1) > + return __fcntl64_2 (__fd, __cmd); > + > + return __fcntl64_alias (__fd, __cmd, __va_arg_pack ()); > +} > +#endif > diff --git a/io/fcntl64_2.c b/io/fcntl64_2.c > new file mode 100644 > index 00000000..6352f524 > --- /dev/null > +++ b/io/fcntl64_2.c > @@ -0,0 +1,33 @@ > +/* _FORTIFY_SOURCE wrapper for fcntl64. > + 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_cmd_needs_arg from bits/fcntl2.h */ > +#undef _FORTIFY_SOURCE > +#define _FORTIFY_SOURCE 1 > + > +#include <fcntl.h> > +#include <stdio.h> > + > +int > +__fcntl64_2 (int fd, int cmd) > +{ > + if (__fcntl_cmd_needs_arg (cmd)) > + __fortify_fail ("invalid fcntl64 call: this cmd requires an argument"); > + > + return __libc_fcntl64 (fd, cmd); > +} > diff --git a/io/fcntl_2.c b/io/fcntl_2.c > new file mode 100644 > index 00000000..fc9303e4 > --- /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_cmd_needs_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_cmd_needs_arg (cmd)) > + __fortify_fail ("invalid fcntl call: this cmd requires an argument"); > + > + return __libc_fcntl (fd, cmd); > +} > diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist > index 6925222f..fa24d577 100644 > --- a/sysdeps/mach/hurd/i386/libc.abilist > +++ b/sysdeps/mach/hurd/i386/libc.abilist > @@ -2294,6 +2294,8 @@ 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 __fcntl64_2 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..efb83b16 100644 > --- a/sysdeps/mach/hurd/x86_64/libc.abilist > +++ b/sysdeps/mach/hurd/x86_64/libc.abilist > @@ -194,6 +194,8 @@ 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 __fcntl64_2 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..86144979 100644 > --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist > @@ -2633,6 +2633,8 @@ 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 __fcntl64_2 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..646c11e3 100644 > --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist > +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist > @@ -2730,6 +2730,8 @@ 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 __fcntl64_2 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..37e9129f 100644 > --- a/sysdeps/unix/sysv/linux/arc/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist > @@ -2394,6 +2394,8 @@ 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 __fcntl64_2 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..4c9b937e 100644 > --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > @@ -514,6 +514,8 @@ 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 __fcntl64_2 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..8dbf72c5 100644 > --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist > @@ -511,6 +511,8 @@ 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 __fcntl64_2 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..b58b2b9c 100644 > --- a/sysdeps/unix/sysv/linux/csky/libc.abilist > +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist > @@ -2670,6 +2670,8 @@ 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 __fcntl64_2 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..c80bb835 100644 > --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist > +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist > @@ -2619,6 +2619,8 @@ 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 __fcntl64_2 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..5a737b3d 100644 > --- a/sysdeps/unix/sysv/linux/i386/libc.abilist > +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist > @@ -2803,6 +2803,8 @@ 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 __fcntl64_2 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..aab6d422 100644 > --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist > @@ -2568,6 +2568,8 @@ 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 __fcntl64_2 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..82da98d2 100644 > --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist > @@ -2154,6 +2154,8 @@ GLIBC_2.36 wprintf F > GLIBC_2.36 write F > GLIBC_2.36 writev F > GLIBC_2.36 wscanf F > +GLIBC_2.38 __fcntl64_2 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..f6c80b46 100644 > --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > @@ -515,6 +515,8 @@ 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 __fcntl64_2 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..dc34ea56 100644 > --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > @@ -2746,6 +2746,8 @@ 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 __fcntl64_2 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..466e4092 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > @@ -2719,6 +2719,8 @@ 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 __fcntl64_2 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..dc27b4e7 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > @@ -2716,6 +2716,8 @@ 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 __fcntl64_2 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..a8dfa647 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > @@ -2711,6 +2711,8 @@ 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 __fcntl64_2 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..4defd8dc 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > @@ -2709,6 +2709,8 @@ 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 __fcntl64_2 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..824b6b4c 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > @@ -2717,6 +2717,8 @@ 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 __fcntl64_2 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..ff4341a8 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > @@ -2619,6 +2619,8 @@ 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 __fcntl64_2 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..ede0e6eb 100644 > --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist > +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist > @@ -2758,6 +2758,8 @@ 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 __fcntl64_2 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..22525fe8 100644 > --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist > +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist > @@ -2140,6 +2140,8 @@ 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 __fcntl64_2 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..2938361e 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > @@ -2773,6 +2773,8 @@ 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 __fcntl64_2 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..e1c70a25 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > @@ -2806,6 +2806,8 @@ 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 __fcntl64_2 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..2ce2d974 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > @@ -2527,6 +2527,8 @@ 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 __fcntl64_2 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..b1024501 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > @@ -2829,6 +2829,8 @@ 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 __fcntl64_2 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..833fb747 100644 > --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > @@ -2396,6 +2396,8 @@ 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 __fcntl64_2 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..cbd85454 100644 > --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > @@ -2596,6 +2596,8 @@ 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 __fcntl64_2 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..1442a0b9 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > @@ -2771,6 +2771,8 @@ 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 __fcntl64_2 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..1a7f4fc7 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > @@ -2564,6 +2564,8 @@ 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 __fcntl64_2 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..3146ce99 100644 > --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > @@ -2626,6 +2626,8 @@ 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 __fcntl64_2 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..31360691 100644 > --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist > @@ -2623,6 +2623,8 @@ 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 __fcntl64_2 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..026e9581 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > @@ -2766,6 +2766,8 @@ 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 __fcntl64_2 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..6ecb0d46 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > @@ -2591,6 +2591,8 @@ 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 __fcntl64_2 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..a37f4ab4 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > @@ -2542,6 +2542,8 @@ 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 __fcntl64_2 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..3b8790f4 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > @@ -2648,6 +2648,8 @@ 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 __fcntl64_2 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 [1] https://patchwork.sourceware.org/project/glibc/list/?series=19418
On Tue, May 23, 2023 at 10:09 PM Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> wrote: > > +# ifndef __USE_FILE_OFFSET64 > > +/* Just fcntl (). */ > > Does this comment adds anything? Also I think we avoid to use '()' on function > definition on comments. These comments were mainly for myself to keep track of the various possible configurations -- I decided to leave them in since the reader of the code might get a little overwhelmed by the combinatorial explosion of the possible configuration variants as well. I can remove these comments (or just this one?) if you would prefer that. > > +__extern_always_inline int > > Should we use __fortify_function also for this case? I think __fortify_function is supposed to be used on the replacement functions themselves, not their helpers? if that's not the case, sure. > > +#ifdef __F_GETOWN_EX > > + case __F_GETOWN_EX: > > + case __F_SETOWN_EX: > > + case __F_SETSIG: > > +#endif > > I think it would be better to condicionalize using __USE_GNU: > > #ifdef __USE_GNU > case F_GETOWN_EX: > case F_SETOWN_EX: > case F_SETSIG: > #endif > > Since the double underscore symbols are implementation defined one and should > not be used by the application. But that would break on the Hurd, no? I could do #ifdef F_GETOWN_EX (without the double underscore), but I wanted to handle __F_GETOWN_EX etc. even if the user has not enabled them (better handle them than not). In other words, this ifdef is meant to check for Hurd vs Linux, not for __USE_GNU vs not. > Should be worried that since we don't have const expressions like newer C++ > that large switch might ended being extra code on every fcntl call? I think > the __builtin_constant_p check below gives compiler enough information to > avoid it, but I am not sure. Yes, __builtin_constant_p is, AFAIK, some compiler magic that "guarantees" (quoted since I'm not sure if it's actually guaranteed, but I've never seen it behave otherwise) that in the true branch the value is treated as a compile-time constant. In practice (see what the tst-fortify compiles to!), with -O2 this whole thing is fully optimized away, and the generated code contains the very same calls to fcntl (or fcntl64, or whatever) that it would if there never was any fortification -- except you get compile-time errors if you forget the argument when it's required. So there's zero run-time cost. If the cmd argument is a c-t const, that is -- otherwise it calls the _2 versions and does the check at runtime, yes. But that's only extra code (as in code size) once, in glibc, not at the call sites. > > + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) > > No implicit check for function that do not return bool: > > if (__fcntl_cmd_needs_arg (__cmd) == 1 ...) Why? Is it just a code style thing? > I think we need also to handle __USE_TIME_BITS64 and add another fcntl debug > symbol to handle; even though for Linux now __fcntl_time64 is just a alias > to __libc_fcntl64. > > It is because we even need to add a proper __fcntl_time64 implementation, > the redirection now does: > > fcntl -> __fcntl64_2 -> __libc_fcntl64 > > Where it should be something like: > > fcntl -> __fcntl_time64_2 -> __fcntl_time64 The idea here was that the 2-argument version of fcntl clearly does not deal with time, either 32- or 64-bit... Sergey
On 23/05/23 16:43, Sergey Bugaev wrote: > On Tue, May 23, 2023 at 10:09 PM Adhemerval Zanella Netto > <adhemerval.zanella@linaro.org> wrote: >>> +# ifndef __USE_FILE_OFFSET64 >>> +/* Just fcntl (). */ >> >> Does this comment adds anything? Also I think we avoid to use '()' on function >> definition on comments. > > These comments were mainly for myself to keep track of the various > possible configurations -- I decided to leave them in since the reader > of the code might get a little overwhelmed by the combinatorial > explosion of the possible configuration variants as well. > > I can remove these comments (or just this one?) if you would prefer that. I am chiming in because it is an installed header, but this should be ok. > >>> +__extern_always_inline int >> >> Should we use __fortify_function also for this case? > > I think __fortify_function is supposed to be used on the replacement > functions themselves, not their helpers? if that's not the case, sure. The __fortify_function mainly adds the artificial attribute, which improves the error message to make on the call site instead of the decorated function. If the error messages from wrong fnctl usage are ok, I think we can skip the __fortify_function usage here. > >>> +#ifdef __F_GETOWN_EX >>> + case __F_GETOWN_EX: >>> + case __F_SETOWN_EX: >>> + case __F_SETSIG: >>> +#endif >> >> I think it would be better to condicionalize using __USE_GNU: >> >> #ifdef __USE_GNU >> case F_GETOWN_EX: >> case F_SETOWN_EX: >> case F_SETSIG: >> #endif >> >> Since the double underscore symbols are implementation defined one and should >> not be used by the application. > > But that would break on the Hurd, no? > > I could do #ifdef F_GETOWN_EX (without the double underscore), but I > wanted to handle __F_GETOWN_EX etc. even if the user has not enabled > them (better handle them than not). In other words, this ifdef is > meant to check for Hurd vs Linux, not for __USE_GNU vs not. But user will actually use F_GETOWN_EX, not __F_GETOWN_EX; so I think check for F_GETOWN_EX define as well. > >> Should be worried that since we don't have const expressions like newer C++ >> that large switch might ended being extra code on every fcntl call? I think >> the __builtin_constant_p check below gives compiler enough information to >> avoid it, but I am not sure. > > Yes, __builtin_constant_p is, AFAIK, some compiler magic that > "guarantees" (quoted since I'm not sure if it's actually guaranteed, > but I've never seen it behave otherwise) that in the true branch the > value is treated as a compile-time constant. > > In practice (see what the tst-fortify compiles to!), with -O2 this > whole thing is fully optimized away, and the generated code contains > the very same calls to fcntl (or fcntl64, or whatever) that it would > if there never was any fortification -- except you get compile-time > errors if you forget the argument when it's required. So there's zero > run-time cost. > > If the cmd argument is a c-t const, that is -- otherwise it calls the > _2 versions and does the check at runtime, yes. But that's only extra > code (as in code size) once, in glibc, not at the call sites. Fair enough. > >>> + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) >> >> No implicit check for function that do not return bool: >> >> if (__fcntl_cmd_needs_arg (__cmd) == 1 ...) > > Why? Is it just a code style thing? Yes, it is from the glibc code style (check 'Boolean Coercions' [1]). [1] https://sourceware.org/glibc/wiki/Style_and_Conventions > >> I think we need also to handle __USE_TIME_BITS64 and add another fcntl debug >> symbol to handle; even though for Linux now __fcntl_time64 is just a alias >> to __libc_fcntl64. >> >> It is because we even need to add a proper __fcntl_time64 implementation, >> the redirection now does: >> >> fcntl -> __fcntl64_2 -> __libc_fcntl64 >> >> Where it should be something like: >> >> fcntl -> __fcntl_time64_2 -> __fcntl_time64 > > The idea here was that the 2-argument version of fcntl clearly does > not deal with time, either 32- or 64-bit... And that's why we don't have a __fcntl_time64 implementation. But Florian has asked to add one anyway if we even eventually need to handle some time related structure. I think we can skip this for now, but at least add a comment stating that if we even need to handle time related field with fcntl we will a new redirection.
Hello, On Tue, May 23, 2023 at 10:15 PM Siddhesh Poyarekar <siddhesh@gotplt.org> wrote: > *_chk but I don't want to block this good work on that. The overall > direction is good IMO Yay, thanks! > - manual/contrib.texi should be updated to mention fcntl Do you mean manual/maint.texi? manual/contrib.texi seems to contain a list of contributors. > - Internal users end up calling __libc_fcntl (see dup2.c or grantpt.c > for example), which will essentially bypass any fortification. This is > not a problem today since we don't build glibc with fortification, but > Frederic Berat[1] has been experimenting with that and we're hoping to > get at least a subset of glibc fortified for 2.38. It would be a shame > to miss fortifying glibc itself. This is again not a problem that would > block this patch, but something to be aware of. Yes, I've thought of this, but I don't know what I could change in this patch to make it friendlier to in-glibc fortification. I've generally done things the same way as the open* fortification does; so I don't think this would be adding any new complications compared to what's already in there. > Given that this will error out at compile time, do we even need this > __fcntl64_2 call? Same as for the open* fortification: this call will only fail at compile time if the cmd is a compile-time constant. If it's not (which is a rare, but valid case), we need to do the check at runtime. Note that if cmd _is_ a compile-time constant and does not require the 3rd arg, this will call the regular fcntl, not the _2 version; the _2 version is only for non-compile-time-const cmd-s. Sergey
On Tue, May 23, 2023 at 11:01 PM Sergey Bugaev <bugaevc@gmail.com> wrote: > Same as for the open* fortification: this call will only fail at > compile time if the cmd is a compile-time constant. If it's not (which > is a rare, but valid case), we need to do the check at runtime. Note > that if cmd _is_ a compile-time constant and does not require the 3rd > arg, this will call the regular fcntl, not the _2 version; the _2 > version is only for non-compile-time-const cmd-s. Ah, no, I see what you mean: you mean we don't strictly speaking need the __fcntl64_2 call immediately following __fcntl_missing_arg. I guess we don't -- maybe the corresponding change needs to be done to the open* fortification as well then. Sergey
On Tue, May 23, 2023 at 10:57 PM Adhemerval Zanella Netto <adhemerval.zanella@linaro.org> wrote: > >>> + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) > >> > >> No implicit check for function that do not return bool: > >> > >> if (__fcntl_cmd_needs_arg (__cmd) == 1 ...) > > > > Why? Is it just a code style thing? > > Yes, it is from the glibc code style (check 'Boolean Coercions' [1]). > > [1] https://sourceware.org/glibc/wiki/Style_and_Conventions [I don't mean to argue, and surely you know better, and not that I care about this], but I read that as saying that implicit integer-to-bool conversions are frowned upon, not ints used as bools (because C used to lack a bool type). In other words: if you have an integer variable that can have many different values and you want to check it against 0, you're supposed to write out the != 0 explicitly. But if what you have is essentially a boolean, but you use int/1/0 instead of bool/true/false, then just checking if (my_bool) should be fine, and doing != 0 would be awkward -- no? I've surely seen glibc code use if (my_bool) without the != 0 when my_bool is declared as an int. __libc_enable_secure is one example. > > The idea here was that the 2-argument version of fcntl clearly does > > not deal with time, either 32- or 64-bit... > > And that's why we don't have a __fcntl_time64 implementation. But Florian > has asked to add one anyway if we even eventually need to handle some time > related structure. > > I think we can skip this for now, but at least add a comment stating that > if we even need to handle time related field with fcntl we will a new > redirection. Hm, either I'm failing to understand what you're saying (which is possible: it is late at night), or maybe I didn't make my point clear: if what you're concerned is what the _2 functions end up calling (__fcntl_time64 vs __libc_fcntl64), then it does not matter because they're only used for 2-argument variant of fcntl, which can not possibly deal with any time-related structures (nor any structures), exactly because there's no third argument where a structure could be passed. The 2-arg variant is basically for simple getters that return an int. But if something is off (wrt time64 vs not) in the main fortification / redirection code, then I surely need to fix that -- then please clarify what specific configuration / case you're talking about. Sergey
On Tue, May 23, 2023, 23:24 Sergey Bugaev <bugaevc@gmail.com> wrote: > if what you're concerned is what the _2 functions end up calling > (__fcntl_time64 vs __libc_fcntl64), then it does not matter because > they're only used for 2-argument variant of fcntl, which can not > possibly deal with any time-related structures (nor any structures), > exactly because there's no third argument where a structure could be > passed. The 2-arg variant is basically for simple getters that return > an int. And now that I think of it, there's also no reason to have separate __fcntl64_2 & __fcntl_2 functions either, is there? Sergey
* Sergey Bugaev via Libc-alpha: > Both open () and fcntl () are "overloaded" to accept either 2 or 3 > arguments; whether the last argument is required 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. A while ago, I looked into implementing this with __builtin_types_compatible_p and __builtin_choose_expr. It seemed feasible (although I didn't complete it), but C++ would require a completely different implementation. I'm not sure if this goes in the right direction. Maybe we should add specialized functions for the common fcntl requests. This way, we'd get compile-time type checking in a far more maintainable manner.
Hello, On Wed, May 24, 2023 at 12:46 AM Florian Weimer <fw@deneb.enyo.de> wrote: > A while ago, I looked into implementing this with > __builtin_types_compatible_p and __builtin_choose_expr. It seemed > feasible (although I didn't complete it), but C++ would require a > completely different implementation. > > I'm not sure if this goes in the right direction. Maybe we should add > specialized functions for the common fcntl requests. This way, we'd > get compile-time type checking in a far more maintainable manner. Interesting -- I have thought of doing type checking, but haven't found a way to make it work. There doesn't seem to be a way to extract an argument value / type out of a __builtin_va_arg_pack. Even if you know that __builtin_va_arg_pack_len () == 1, you cannot do: int arg = __builtin_va_arg_pack (); or int __fcntl3_int (int fd, int cmd, int arg); __fcntl3_int (fd, cmd, __builtin_va_arg_pack ()); In other words: __builtin_va_arg_pack () does not behave like a macro that gets textually expanded to the anonymous argument(s), but really as a value of the "..." "argument". You can do typeof (__builtin_va_arg_pack ()), but it just always ends up being an int, no matter what you actually pass. You could use the regular va_arg (), but that of course requires you to specify the type to cast to yourself, so no point in doing that. Maybe it's possible to achieve with some preprocessor trickery? Sergey
* Sergey Bugaev via Libc-alpha: > Hello, > > On Wed, May 24, 2023 at 12:46 AM Florian Weimer <fw@deneb.enyo.de> wrote: >> A while ago, I looked into implementing this with >> __builtin_types_compatible_p and __builtin_choose_expr. It seemed >> feasible (although I didn't complete it), but C++ would require a >> completely different implementation. >> >> I'm not sure if this goes in the right direction. Maybe we should add >> specialized functions for the common fcntl requests. This way, we'd >> get compile-time type checking in a far more maintainable manner. > > Interesting -- I have thought of doing type checking, but haven't > found a way to make it work. > > There doesn't seem to be a way to extract an argument value / type out > of a __builtin_va_arg_pack. Even if you know that > __builtin_va_arg_pack_len () == 1, you cannot do: > > int arg = __builtin_va_arg_pack (); > > or > > int __fcntl3_int (int fd, int cmd, int arg); > __fcntl3_int (fd, cmd, __builtin_va_arg_pack ()); > > In other words: __builtin_va_arg_pack () does not behave like a macro > that gets textually expanded to the anonymous argument(s), but really > as a value of the "..." "argument". In my attempt, the top level looks like this: +#define fcntl(fd, cmd, ...) \ + (__builtin_constant_p (cmd) \ + ? __builtin_choose_expression \ + (__fcntl_is_void (cmd), __fcntl_void (fd, cmd, __VA_ARGS__), \ + __builtin_choose_expression \ + (__fcntl_is_int (cmd), __fcntl_int (fd, cmd, __VA_ARGS__), \ + __builtin_choose_expression \ + (__fcntl_is_flock_const (cmd), __fcntl_flock_const (fd, cmd, __VA_ARGS__), \ + __builtin_choose_expression \ + (__fcntl_is_flock (cmd), __fcntl_flock (fd, cmd, __VA_ARGS__), \ + __builtin_chose_expression \ + (__fcntl_is_flock64_const (cmd), __fcntl_flock64_const (fd, cmd, __VA_ARGS__), \ + __builtin_choose_expression \ + (__fcntl_is_flock64 (cmd), __fcntl_flock64 (fd, cmd, __VA_ARGS__), \ + __builtin_choose_expression \ + (__fcntl_is_flock32_const (cmd), __fcntl_flock32_const (fd, cmd, __VA_ARGS__), \ + __builtin_choose_expression \ + (__fcntl_is_flock32 (cmd), __fcntl_flock32 (fd, cmd, __VA_ARGS__), \ + __fcntl_unchecked (fd, cmd, __VA_ARGS__))))))))) \ + : __fcntl_unchecked (fd, cmd, __VA_ARGS__)) IIRC, it doesn't quite work because __builtin_choose_expression only suppresses errors, but not warnings, in the branch that wasn't chosen. 8-( Maybe this is something that could be fixed with _Generic, using __builtin_choose_expression for the __fcntl_is_void check only. The type predicts look like this: +#ifdef F_SETLK64 +# define __fcntl_is_flock64_const(cmd) \ + ((cmd) == F_SETLK64 || (cmd) == F_SETLKW64) +# define __fcntl_is_flock64(cmd) ((cmd) == F_GETLK64) +#else +# define __fcntl_is_flock64_const(cmd) 0 +# define __fcntl_is_flock64(cmd) 0 +#endif The helper wrappers are simple redirects to the existing exported function, with transparent unions to handle the aliases. +#if defined (__USE_LARGEFILE64) && defined (__OFF_T_MATCHES_OFF64_T) +typedef union __attribute__ ((__transparent_union__)) +{ + struct flock *__flock; + struct flock64 *__flock64; +} __flock_pointer; +typedef union __attribute__ ((__transparent_union__)) +{ + const struct flock *__flock; + const struct flock64 *__flock64; +} __flock_const_pointer; +#else /* flock and flock64 are distinct */ +typedef struct flock *__flock_pointer; +typedef const struct flock *__flock_const_pointer; +#endif + +int __REDIRECT (__fcntl_flock, (int, int, __flock_pointer), __fcntl_chk) __wur; +int __REDIRECT (__fcntl_flock_const, (int, int, __flock_const_pointer), + __fcntl_chk) __wur; +int __REDIRECT (__fcntl_flock32, (int, int, struct flock *), + __fcntl_chk) __wur; +int __REDIRECT (__fcntl_flock32_const, (int, int, const struct flock *), + __fcntl_chk) __wur; +#ifdef __USE_LARGEFILE64 +int __REDIRECT (__fcntl_flock64, (int, int, struct flock64 *), + __fcntl_chk) __wur; +int __REDIRECT (__fcntl_flock64_const, (int, int, const struct flock64 *), + __fcntl_chk) __wur; +#endif The compiler will then warn about the type mismatches (-Wincompatible-pointer-types is not an error by default, for backwards compatibility). But as I said, I don't think this approach worked because __builtin_choose_expression does not suppress those warnings. I'm attaching my broken patch. It's based on commit ef4f97648dc9584 (from 2016). Thanks, Florian
On Wed, May 24, 2023 at 11:29 AM Florian Weimer <fweimer@redhat.com> wrote:> > I'm attaching my broken patch. It's based on commit ef4f97648dc9584 > (from 2016). Thank you, that's helpful. A couple more issues with your patch (I understand that it's WIP and broken): 1. You're doing int __fcntl_chk (int, int, ...); int __REDIRECT (__fcntl_int, (int, int, int __arg), __fcntl_chk); This is not OK, the ABI may be different between vararg- and non-vararg functions. 2. It doesn't do the runtime check if called with 2 args and non-c-t-const cmd. > IIRC, it doesn't quite work because __builtin_choose_expression only > suppresses errors, but not warnings, in the branch that wasn't chosen. 8-( > > Maybe this is something that could be fixed with _Generic, using > __builtin_choose_expression for the __fcntl_is_void check only. Yes -- I've sketched something up using _Generic and it appears to work great: https://godbolt.org/z/8zdzo3T5Y It does do preprocessor trickery ("friendship ended with __builtin_va_arg_pack_len, now __VA_OPT__ is my best friend") and does not use __builtin_choose_expr at all, so should be C++-compatible too (try with -xc++). This, too, is obviously a prototype, and does not do runtime _2 checking nor 64-bit handling and so on. What do you think? Is this direction worth pursuing? Sergey
* Sergey Bugaev: > On Wed, May 24, 2023 at 11:29 AM Florian Weimer <fweimer@redhat.com> wrote:> >> I'm attaching my broken patch. It's based on commit ef4f97648dc9584 >> (from 2016). > > Thank you, that's helpful. > > A couple more issues with your patch (I understand that it's WIP and broken): > > 1. You're doing > > int __fcntl_chk (int, int, ...); > int __REDIRECT (__fcntl_int, (int, int, int __arg), __fcntl_chk); > > This is not OK, the ABI may be different between vararg- and > non-vararg functions. Right, I planned to make __fcntl_chk non-variadic in its implementation. We unconditionally read the argument already. Variadic calls to non-variadic functions are okay for our ABIs, we need that for K&R compatibility anyway. > 2. It doesn't do the runtime check if called with 2 args and > non-c-t-const cmd. That's possible, I don't remember. >> IIRC, it doesn't quite work because __builtin_choose_expression only >> suppresses errors, but not warnings, in the branch that wasn't chosen. 8-( >> >> Maybe this is something that could be fixed with _Generic, using >> __builtin_choose_expression for the __fcntl_is_void check only. > > Yes -- I've sketched something up using _Generic and it appears to > work great: https://godbolt.org/z/8zdzo3T5Y > > It does do preprocessor trickery ("friendship ended with > __builtin_va_arg_pack_len, now __VA_OPT__ is my best friend") and does > not use __builtin_choose_expr at all, so should be C++-compatible too > (try with -xc++). Right, it doesn't look too bad actually. > This, too, is obviously a prototype, and does not do runtime _2 > checking nor 64-bit handling and so on. > > What do you think? Is this direction worth pursuing? I think so, yes. Thanks, Florian
On 2023-05-24 07:18, Florian Weimer via Libc-alpha wrote: >>> IIRC, it doesn't quite work because __builtin_choose_expression only >>> suppresses errors, but not warnings, in the branch that wasn't chosen. 8-( >>> >>> Maybe this is something that could be fixed with _Generic, using >>> __builtin_choose_expression for the __fcntl_is_void check only. >> >> Yes -- I've sketched something up using _Generic and it appears to >> work great: https://godbolt.org/z/8zdzo3T5Y >> >> It does do preprocessor trickery ("friendship ended with >> __builtin_va_arg_pack_len, now __VA_OPT__ is my best friend") and does >> not use __builtin_choose_expr at all, so should be C++-compatible too >> (try with -xc++). > > Right, it doesn't look too bad actually. > >> This, too, is obviously a prototype, and does not do runtime _2 >> checking nor 64-bit handling and so on. >> >> What do you think? Is this direction worth pursuing? > > I think so, yes. Please be sure to make the _Generic bits conditional on __USE_ISOC11. Thanks, Sid
On 23/05/23 17:24, Sergey Bugaev wrote: > On Tue, May 23, 2023 at 10:57 PM Adhemerval Zanella Netto > <adhemerval.zanella@linaro.org> wrote: >>>>> + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) >>>> >>>> No implicit check for function that do not return bool: >>>> >>>> if (__fcntl_cmd_needs_arg (__cmd) == 1 ...) >>> >>> Why? Is it just a code style thing? >> >> Yes, it is from the glibc code style (check 'Boolean Coercions' [1]). >> >> [1] https://sourceware.org/glibc/wiki/Style_and_Conventions > > [I don't mean to argue, and surely you know better, and not that I > care about this], but I read that as saying that implicit > integer-to-bool conversions are frowned upon, not ints used as bools > (because C used to lack a bool type). In other words: if you have an > integer variable that can have many different values and you want to > check it against 0, you're supposed to write out the != 0 explicitly. > But if what you have is essentially a boolean, but you use int/1/0 > instead of bool/true/false, then just checking if (my_bool) should be > fine, and doing != 0 would be awkward -- no? > > I've surely seen glibc code use if (my_bool) without the != 0 when > my_bool is declared as an int. __libc_enable_secure is one example. The interger as bool is not the problem, specially on a installed header that won't be easy to use 'bool' (due namespace pollution, standard conformance, etc.). And sure some usage of implicit conversions might have slip in review, but I think it should follow the code guide lines anyway (unless we revise it). > >>> The idea here was that the 2-argument version of fcntl clearly does >>> not deal with time, either 32- or 64-bit... >> >> And that's why we don't have a __fcntl_time64 implementation. But Florian >> has asked to add one anyway if we even eventually need to handle some time >> related structure. >> >> I think we can skip this for now, but at least add a comment stating that >> if we even need to handle time related field with fcntl we will a new >> redirection. > > Hm, either I'm failing to understand what you're saying (which is > possible: it is late at night), or maybe I didn't make my point clear: > > if what you're concerned is what the _2 functions end up calling > (__fcntl_time64 vs __libc_fcntl64), then it does not matter because > they're only used for 2-argument variant of fcntl, which can not > possibly deal with any time-related structures (nor any structures), > exactly because there's no third argument where a structure could be > passed. The 2-arg variant is basically for simple getters that return > an int. > > But if something is off (wrt time64 vs not) in the main fortification > / redirection code, then I surely need to fix that -- then please > clarify what specific configuration / case you're talking about. Right, I see your point now. > Ah, no, I see what you mean: you mean we don't strictly speaking need > the __fcntl64_2 call immediately following __fcntl_missing_arg. > > I guess we don't -- maybe the corresponding change needs to be done to > the open* fortification as well then. Agree.
On Mai 24 2023, Siddhesh Poyarekar wrote:
> Please be sure to make the _Generic bits conditional on __USE_ISOC11.
That's not enough. GCC 4.7 supports C11, but _Generic has only been
added in GCC 4.9.
* Andreas Schwab: > On Mai 24 2023, Siddhesh Poyarekar wrote: > >> Please be sure to make the _Generic bits conditional on __USE_ISOC11. > > That's not enough. GCC 4.7 supports C11, but _Generic has only been > added in GCC 4.9. We also generally do not prevent the use of compiler extensions in strict feature modes. I think this should use a compiler version check and maybe a fallback check against C17 compiler support if we do not need any extensions (assuming that all C17 compilers implement _Generic, so that an exception like the one you mentioned for GCC does not apply vis-a-vis C17). Thanks, Florian
On Wed, May 24, 2023 at 3:18 PM Florian Weimer <fweimer@redhat.com> wrote: > We also generally do not prevent the use of compiler extensions in > strict feature modes. I think this should use a compiler version check > and maybe a fallback check against C17 compiler support if we do not > need any extensions (assuming that all C17 compilers implement _Generic, > so that an exception like the one you mentioned for GCC does not apply > vis-a-vis C17). Do I understand this correctly? -- you want the check to be #if (__STDC_VERSION__ >= 201710L) || (__GNUC_PREREQ (4, 9) && __STDC_VERSION__ >= 201112L) right? Why even care for compilers other than modern GCC (and Clang pretending to be GCC), considering the fortifications use very GCC-specific intrinsics (__builtin_*, attributes)? Sergey
* Sergey Bugaev: > On Wed, May 24, 2023 at 3:18 PM Florian Weimer <fweimer@redhat.com> wrote: >> We also generally do not prevent the use of compiler extensions in >> strict feature modes. I think this should use a compiler version check >> and maybe a fallback check against C17 compiler support if we do not >> need any extensions (assuming that all C17 compilers implement _Generic, >> so that an exception like the one you mentioned for GCC does not apply >> vis-a-vis C17). > > Do I understand this correctly? -- you want the check to be > > #if (__STDC_VERSION__ >= 201710L) || (__GNUC_PREREQ (4, 9) && > __STDC_VERSION__ >= 201112L) > > right? More like this: #if __STDC_VERSION__ >= 201710L) || __GNUC_PREREQ (4, 9) If you have GCC 4.9, __STDC_VERSION__ does not matter if you use __extension__ in front of _Generic (untested). Clang would benefit from another version conditional. But we may not need _Generic after all. > Why even care for compilers other than modern GCC (and Clang > pretending to be GCC), considering the fortifications use very > GCC-specific intrinsics (__builtin_*, attributes)? Some of us want to reproduce things with older compilers, for bisecting regressions for example. For that, the headers better remain compatible. And GCC 4.8 is still very widely used (although not with current GCC headers, admittedly). Thanks, Florian
On Wed, May 24, 2023 at 3:45 PM Florian Weimer <fweimer@redhat.com> wrote: > If you have GCC 4.9, __STDC_VERSION__ does not matter if you use > __extension__ in front of _Generic (untested). Clang would benefit from > another version conditional. So *that's* what __extension__ is for! Makes sense, thanks. > But we may not need _Generic after all. Indeed, this seems to work just as well: #define __fcntl_type_check(cmd, arg) \ (__fcntl_is_int (cmd) ? __builtin_types_compatible_p (typeof (arg), int) : \ (__fcntl_is_flock (cmd) ? __builtin_types_compatible_p (typeof (arg), struct flock *) : 1)) And __builtin_types_compatible_p appears to have been introduced in GCC 3.1. Sergey
* Sergey Bugaev: > On Wed, May 24, 2023 at 3:45 PM Florian Weimer <fweimer@redhat.com> wrote: >> If you have GCC 4.9, __STDC_VERSION__ does not matter if you use >> __extension__ in front of _Generic (untested). Clang would benefit from >> another version conditional. > > So *that's* what __extension__ is for! Makes sense, thanks. I'm not 100% sure if we need it because _Generic is reserved in any standards version. >> But we may not need _Generic after all. > > Indeed, this seems to work just as well: > > #define __fcntl_type_check(cmd, arg) > \ > (__fcntl_is_int (cmd) ? __builtin_types_compatible_p (typeof (arg), > int) : \ > (__fcntl_is_flock (cmd) ? __builtin_types_compatible_p (typeof > (arg), struct flock *) : 1)) Fair enough. This needs __typeof (or maybe __extension__ __typeof), by the way. Thanks, Florian
diff --git a/include/fcntl.h b/include/fcntl.h index d788db2e..7742c002 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -32,6 +32,9 @@ 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); +extern int __fcntl64_2 (int __fd, int __cmd); + /* Makes open () & friends faster on the Hurd, but can only be used (without altering user-visible behavior) when we're sure that the file we're opening diff --git a/io/Makefile b/io/Makefile index f72571cd..350807ee 100644 --- a/io/Makefile +++ b/io/Makefile @@ -41,7 +41,7 @@ routines := \ mkdir mkdirat \ open open_2 open64 open64_2 openat openat_2 openat64 openat64_2 \ read write lseek lseek64 access euidaccess faccessat \ - fcntl fcntl64 flock lockf lockf64 \ + fcntl fcntl_2 fcntl64 fcntl64_2 flock lockf lockf64 \ close dup dup2 dup3 pipe pipe2 \ creat creat64 \ chdir fchdir \ diff --git a/io/Versions b/io/Versions index 4e195408..8409e105 100644 --- a/io/Versions +++ b/io/Versions @@ -140,6 +140,10 @@ libc { GLIBC_2.34 { closefrom; } + GLIBC_2.38 { + __fcntl_2; + __fcntl64_2; + } GLIBC_PRIVATE { __libc_fcntl64; __fcntl_nocancel; diff --git a/io/bits/fcntl2.h b/io/bits/fcntl2.h index bdb48fa8..beb3a628 100644 --- a/io/bits/fcntl2.h +++ b/io/bits/fcntl2.h @@ -170,3 +170,142 @@ openat64 (int __fd, const char *__path, int __oflag, ...) } # endif #endif + +#ifndef __USE_TIME_BITS64 + +# ifndef __USE_FILE_OFFSET64 +/* Just fcntl (). */ +extern int __fcntl_2 (int __fd, int __cmd); +extern int __REDIRECT (__fcntl_alias, (int __fd, int __cmd, ...), fcntl); +# else +/* fcntl.h redirects fcntl () to fcntl64 (). */ +extern int __REDIRECT (__fcntl_2, (int __fd, int __cmd), __fcntl64_2); +extern int __REDIRECT (__fcntl_alias, (int __fd, int __cmd, ...), fcntl64); +# endif /* __USE_FILE_OFFSET64 */ + +# ifdef __USE_LARGEFILE64 +/* Just fcntl64 (). */ +extern int __fcntl64_2 (int __fd, int __cmd); +extern int __REDIRECT (__fcntl64_alias, (int __fd, int __cmd, ...), fcntl64); +# endif + +#else /* __USE_TIME_BITS64 */ + +/* fcntl.h redirects both fcntl () and fcntl64 () to __fcntl_time64 (). */ +extern int __fcntl64_2 (int __fd, int __cmd); +extern int __REDIRECT (__fcntl_2, (int __fd, int __cmd), __fcntl64_2); +extern int __REDIRECT_NTH (__fcntl_alias, (int __fd, int __cmd, ...), + __fcntl_time64); +extern int __REDIRECT_NTH (__fcntl64_alias, (int __fd, int __cmd, ...), + __fcntl_time64); +#endif /* __USE_TIME_BITS64 */ + +__errordecl (__fcntl_too_many_args, + "fcntl can be called either with 2 or 3 arguments, not more"); +__errordecl (__fcntl_missing_arg, + "fcntl with with this cmd needs 3 arguments"); + +__extern_always_inline int +__fcntl_cmd_needs_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; + + case F_GETFD: + case F_GETFL: +#ifdef F_GETOWN + case F_GETOWN: +#endif +#ifdef __F_GETSIG + case __F_GETSIG: +#endif +#ifdef F_GETLEASE + case F_GETLEASE: + case F_GETPIPE_SZ: + case F_GET_SEALS: +#endif + /* For any cmd value we don't know about, + default to not requiring an argument. */ + default: + return 0; + } +} + +__fortify_function int +fcntl (int __fd, int __cmd, ...) +{ + if (__va_arg_pack_len () > 1) + __fcntl_too_many_args (); + + if (__builtin_constant_p (__cmd)) + { + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) + { + __fcntl_missing_arg (); + return __fcntl_2 (__fd, __cmd); + } + return __fcntl_alias (__fd, __cmd, __va_arg_pack ()); + } + + if (__va_arg_pack_len () < 1) + return __fcntl_2 (__fd, __cmd); + + return __fcntl_alias (__fd, __cmd, __va_arg_pack ()); +} + +#ifdef __USE_LARGEFILE64 +__fortify_function int +fcntl64 (int __fd, int __cmd, ...) +{ + if (__va_arg_pack_len () > 1) + __fcntl_too_many_args (); + + if (__builtin_constant_p (__cmd)) + { + if (__fcntl_cmd_needs_arg (__cmd) && __va_arg_pack_len () < 1) + { + __fcntl_missing_arg (); + return __fcntl64_2 (__fd, __cmd); + } + return __fcntl64_alias (__fd, __cmd, __va_arg_pack ()); + } + + if (__va_arg_pack_len () < 1) + return __fcntl64_2 (__fd, __cmd); + + return __fcntl64_alias (__fd, __cmd, __va_arg_pack ()); +} +#endif diff --git a/io/fcntl64_2.c b/io/fcntl64_2.c new file mode 100644 index 00000000..6352f524 --- /dev/null +++ b/io/fcntl64_2.c @@ -0,0 +1,33 @@ +/* _FORTIFY_SOURCE wrapper for fcntl64. + 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_cmd_needs_arg from bits/fcntl2.h */ +#undef _FORTIFY_SOURCE +#define _FORTIFY_SOURCE 1 + +#include <fcntl.h> +#include <stdio.h> + +int +__fcntl64_2 (int fd, int cmd) +{ + if (__fcntl_cmd_needs_arg (cmd)) + __fortify_fail ("invalid fcntl64 call: this cmd requires an argument"); + + return __libc_fcntl64 (fd, cmd); +} diff --git a/io/fcntl_2.c b/io/fcntl_2.c new file mode 100644 index 00000000..fc9303e4 --- /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_cmd_needs_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_cmd_needs_arg (cmd)) + __fortify_fail ("invalid fcntl call: this cmd requires an argument"); + + return __libc_fcntl (fd, cmd); +} diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index 6925222f..fa24d577 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2294,6 +2294,8 @@ 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 __fcntl64_2 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..efb83b16 100644 --- a/sysdeps/mach/hurd/x86_64/libc.abilist +++ b/sysdeps/mach/hurd/x86_64/libc.abilist @@ -194,6 +194,8 @@ 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 __fcntl64_2 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..86144979 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2633,6 +2633,8 @@ 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 __fcntl64_2 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..646c11e3 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2730,6 +2730,8 @@ 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 __fcntl64_2 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..37e9129f 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2394,6 +2394,8 @@ 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 __fcntl64_2 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..4c9b937e 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -514,6 +514,8 @@ 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 __fcntl64_2 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..8dbf72c5 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -511,6 +511,8 @@ 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 __fcntl64_2 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..b58b2b9c 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2670,6 +2670,8 @@ 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 __fcntl64_2 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..c80bb835 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2619,6 +2619,8 @@ 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 __fcntl64_2 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..5a737b3d 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2803,6 +2803,8 @@ 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 __fcntl64_2 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..aab6d422 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2568,6 +2568,8 @@ 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 __fcntl64_2 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..82da98d2 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2154,6 +2154,8 @@ GLIBC_2.36 wprintf F GLIBC_2.36 write F GLIBC_2.36 writev F GLIBC_2.36 wscanf F +GLIBC_2.38 __fcntl64_2 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..f6c80b46 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -515,6 +515,8 @@ 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 __fcntl64_2 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..dc34ea56 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2746,6 +2746,8 @@ 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 __fcntl64_2 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..466e4092 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2719,6 +2719,8 @@ 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 __fcntl64_2 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..dc27b4e7 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2716,6 +2716,8 @@ 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 __fcntl64_2 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..a8dfa647 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2711,6 +2711,8 @@ 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 __fcntl64_2 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..4defd8dc 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2709,6 +2709,8 @@ 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 __fcntl64_2 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..824b6b4c 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2717,6 +2717,8 @@ 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 __fcntl64_2 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..ff4341a8 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2619,6 +2619,8 @@ 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 __fcntl64_2 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..ede0e6eb 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2758,6 +2758,8 @@ 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 __fcntl64_2 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..22525fe8 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2140,6 +2140,8 @@ 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 __fcntl64_2 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..2938361e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2773,6 +2773,8 @@ 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 __fcntl64_2 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..e1c70a25 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2806,6 +2806,8 @@ 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 __fcntl64_2 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..2ce2d974 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2527,6 +2527,8 @@ 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 __fcntl64_2 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..b1024501 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2829,6 +2829,8 @@ 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 __fcntl64_2 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..833fb747 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2396,6 +2396,8 @@ 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 __fcntl64_2 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..cbd85454 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2596,6 +2596,8 @@ 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 __fcntl64_2 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..1442a0b9 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2771,6 +2771,8 @@ 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 __fcntl64_2 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..1a7f4fc7 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2564,6 +2564,8 @@ 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 __fcntl64_2 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..3146ce99 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2626,6 +2626,8 @@ 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 __fcntl64_2 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..31360691 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2623,6 +2623,8 @@ 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 __fcntl64_2 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..026e9581 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2766,6 +2766,8 @@ 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 __fcntl64_2 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..6ecb0d46 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2591,6 +2591,8 @@ 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 __fcntl64_2 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..a37f4ab4 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2542,6 +2542,8 @@ 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 __fcntl64_2 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..3b8790f4 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2648,6 +2648,8 @@ 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 __fcntl64_2 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
Both open () and fcntl () are "overloaded" to accept either 2 or 3 arguments; whether the last argument is required 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 The abilists have been modified with 'make update-abi-all'. Signed-off-by: Sergey Bugaev <bugaevc@gmail.com> --- include/fcntl.h | 3 + io/Makefile | 2 +- io/Versions | 4 + io/bits/fcntl2.h | 139 ++++++++++++++++++ io/fcntl64_2.c | 33 +++++ io/fcntl_2.c | 33 +++++ sysdeps/mach/hurd/i386/libc.abilist | 2 + sysdeps/mach/hurd/x86_64/libc.abilist | 2 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 + sysdeps/unix/sysv/linux/arc/libc.abilist | 2 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 + sysdeps/unix/sysv/linux/csky/libc.abilist | 2 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 + sysdeps/unix/sysv/linux/i386/libc.abilist | 2 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 2 + .../sysv/linux/loongarch/lp64/libc.abilist | 2 + .../sysv/linux/m68k/coldfire/libc.abilist | 2 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 + .../sysv/linux/microblaze/be/libc.abilist | 2 + .../sysv/linux/microblaze/le/libc.abilist | 2 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 2 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 2 + .../sysv/linux/mips/mips64/n32/libc.abilist | 2 + .../sysv/linux/mips/mips64/n64/libc.abilist | 2 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 2 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 2 + .../powerpc/powerpc32/nofpu/libc.abilist | 2 + .../linux/powerpc/powerpc64/be/libc.abilist | 2 + .../linux/powerpc/powerpc64/le/libc.abilist | 2 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 2 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 2 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 2 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 2 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 + .../sysv/linux/sparc/sparc32/libc.abilist | 2 + .../sysv/linux/sparc/sparc64/libc.abilist | 2 + .../unix/sysv/linux/x86_64/64/libc.abilist | 2 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 2 + 42 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 io/fcntl64_2.c create mode 100644 io/fcntl_2.c