From: Adhemerval Zanella Date: Wed, 4 Apr 2018 14:24:15 +0000 (-0300) Subject: Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251) X-Git-Tag: glibc-2.28~156 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=06ab719d30b;p=thirdparty%2Fglibc.git Fix Linux fcntl OFD locks for non-LFS architectures (BZ#20251) This patch fixes the OFD ("file private") locks for architectures that support non-LFS flock definition (__USE_FILE_OFFSET64 not defined). The issue in this case is both F_OFD_{GETLK,SETLK,SETLKW} and F_{SET,GET}L{W}K64 expects a flock64 argument and when using old F_OFD_* flags with a non LFS flock argument the kernel might interpret the underlying data wrongly. Kernel idea originally was to avoid using such flags in non-LFS syscall, but since GLIBC uses fcntl with LFS semantic as default it is possible to provide the functionality and avoid the bogus struct kernel passing by adjusting the struct manually for the required flags. The idea follows other LFS interfaces that provide two symbols: 1. A new LFS fcntl64 is added on default ABI with the usual macros to select it for FILE_OFFSET_BITS=64. 2. The Linux non-LFS fcntl use a stack allocated struct flock64 for F_OFD_{GETLK,SETLK,SETLKW} copy the results on the user provided struct. 3. Keep a compat symbol with old broken semantic for architectures that do not define __OFF_T_MATCHES_OFF64_T. So for architectures which defines __USE_FILE_OFFSET64, fcntl64 will aliased to fcntl and no adjustment would be required. So to actually use F_OFD_* with LFS support the source must be built with LFS support (_FILE_OFFSET_BITS=64). Also F_OFD_SETLKW command is handled a cancellation point, as for F_SETLKW{64}. Checked on x86_64-linux-gnu and i686-linux-gnu. [BZ #20251] * NEWS: Mention fcntl64 addition. * csu/check_fds.c: Replace __fcntl_nocancel by __fcntl64_nocancel. * login/utmp_file.c: Likewise. * sysdeps/posix/fdopendir.c: Likewise. * sysdeps/posix/opendir.c: Likewise. * sysdeps/unix/pt-fcntl.c: Likewise. * include/fcntl.h (__libc_fcntl64, __fcntl64, __fcntl64_nocancel_adjusted): New prototype. (__fcntl_nocancel_adjusted): Remove prototype. * io/Makefile (routines): Add fcntl64. (CFLAGS-fcntl64.c): New rule. * io/Versions [GLIBC_2.28] (fcntl64): New symbol. [GLIBC_PRIVATE] (__libc_fcntl): Rename to __libc_fcntl64. * io/fcntl.h (fcntl64): Add prototype and redirect if __USE_FILE_OFFSET64 is defined. * io/fcntl64.c: New file. * manual/llio.text: Add a note for which commands fcntl acts a cancellation point. * nptl/Makefile (CFLAGS-fcntl64.c): New rule. * sysdeps/mach/hurd/fcntl.c: Alias fcntl to fcntl64 symbols. * sysdeps/mach/hurd/i386/libc.abilist [GLIBC_2.28] (fcntl, fcntl64): New symbols. * sysdeps/unix/sysv/linux/fcntl.c (__libc_fcntl): Fix F_GETLK64, F_OFD_GETLK, F_SETLK64, F_SETLKW64, F_OFD_SETLK, and F_OFD_SETLKW for non-LFS case. * sysdeps/unix/sysv/linux/fcntl64.c: New file. * sysdeps/unix/sysv/linux/fcntl_nocancel.c (__fcntl_nocancel): Rename to __fcntl64_nocancel. (__fcntl_nocancel_adjusted): Rename to __fcntl64_nocancel_adjusted. * sysdeps/unix/sysv/linux/not-cancel.h (__fcntl_nocancel): Rename to __fcntl64_nocancel. * sysdeps/unix/sysv/linux/tst-ofdlocks.c: New file. * sysdeps/unix/sysv/linux/tst-ofdlocks-compat.c: Likewise. * sysdeps/unix/sysv/linux/Makefile (tests): Add tst-ofdlocks. (tests-internal): Add tst-ofdlocks-compat. * sysdeps/unix/sysv/linux/aarch64/libc.abilist [GLIBC_2.28] (fcntl64): New symbol. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/arm/libc.abilist [GLIBC_2.28] (fcntl, fcntl64): Likewise. * sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/i386/libc.abilis: Likewise. * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise. --- diff --git a/ChangeLog b/ChangeLog index eaee727677b..2eeeabf2ad0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,71 @@ +2018-06-26 Adhemerval Zanella + + [BZ #20251] + * NEWS: Mention fcntl64 addition. + * csu/check_fds.c: Replace __fcntl_nocancel by __fcntl64_nocancel. + * login/utmp_file.c: Likewise. + * sysdeps/posix/fdopendir.c: Likewise. + * sysdeps/posix/opendir.c: Likewise. + * sysdeps/unix/pt-fcntl.c: Likewise. + * include/fcntl.h (__libc_fcntl64, __fcntl64, + __fcntl64_nocancel_adjusted): New prototype. + (__fcntl_nocancel_adjusted): Remove prototype. + * io/Makefile (routines): Add fcntl64. + (CFLAGS-fcntl64.c): New rule. + * io/Versions [GLIBC_2.28] (fcntl64): New symbol. + [GLIBC_PRIVATE] (__libc_fcntl): Rename to __libc_fcntl64. + * io/fcntl.h (fcntl64): Add prototype and redirect if + __USE_FILE_OFFSET64 is defined. + * io/fcntl64.c: New file. + * manual/llio.text: Add a note for which commands fcntl acts a + cancellation point. + * nptl/Makefile (CFLAGS-fcntl64.c): New rule. + * sysdeps/mach/hurd/fcntl.c: Alias fcntl to fcntl64 symbols. + * sysdeps/mach/hurd/i386/libc.abilist [GLIBC_2.28] (fcntl, fcntl64): + New symbols. + * sysdeps/unix/sysv/linux/fcntl.c (__libc_fcntl): Fix F_GETLK64, + F_OFD_GETLK, F_SETLK64, F_SETLKW64, F_OFD_SETLK, and F_OFD_SETLKW for + non-LFS case. + * sysdeps/unix/sysv/linux/fcntl64.c: New file. + * sysdeps/unix/sysv/linux/fcntl_nocancel.c (__fcntl_nocancel): Rename + to __fcntl64_nocancel. + (__fcntl_nocancel_adjusted): Rename to __fcntl64_nocancel_adjusted. + * sysdeps/unix/sysv/linux/not-cancel.h (__fcntl_nocancel): Rename + to __fcntl64_nocancel. + * sysdeps/generic/not-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/tst-ofdlocks.c: New file. + * sysdeps/unix/sysv/linux/Makefile (tests): Add tst-ofdlocks. + * sysdeps/unix/sysv/linux/aarch64/libc.abilist [GLIBC_2.28] + (fcntl64): New symbol. + * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. + * sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/arm/libc.abilist [GLIBC_2.28] (fcntl, + fcntl64): Likewise. + * sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/i386/libc.abilis: Likewise. + * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist: + Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist: + Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise. + 2018-06-26 Florian Weimer Run thread shutdown functions in an explicit order. diff --git a/NEWS b/NEWS index db7c1291fd1..9d6fc08eb3c 100644 --- a/NEWS +++ b/NEWS @@ -110,6 +110,12 @@ Deprecated and removed features, and other changes affecting compatibility: restriction (rejecting '_' in host names, among other things) has been removed, for increased compatibility with non-IDN name resolution. +* The fcntl function now have a Long File Support variant named fcntl64. It + is added to fix some Linux Open File Description (OFD) locks usage on non + LFS mode. As for others *64 functions, fcntl64 semantics are analogous with + fcntl and LFS support is handled transparently. Also for Linux, the OFD + locks act as a cancellation entrypoint. + Changes to build and runtime requirements: [Add changes to build and runtime requirements here] diff --git a/csu/check_fds.c b/csu/check_fds.c index 605ee4f3f45..ad1763b3988 100644 --- a/csu/check_fds.c +++ b/csu/check_fds.c @@ -39,7 +39,7 @@ static void check_one_fd (int fd, int mode) { - if (__builtin_expect (__fcntl_nocancel (fd, F_GETFD), 0) == -1 + if (__builtin_expect (__fcntl64_nocancel (fd, F_GETFD), 0) == -1 && errno == EBADF) { const char *name; diff --git a/include/fcntl.h b/include/fcntl.h index 966f797890d..be435047bc8 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -10,11 +10,16 @@ extern int __libc_open (const char *file, int oflag, ...); libc_hidden_proto (__libc_open) extern int __libc_fcntl (int fd, int cmd, ...); libc_hidden_proto (__libc_fcntl) -extern int __fcntl_nocancel_adjusted (int fd, int cmd, void *arg) attribute_hidden; +extern int __fcntl64_nocancel_adjusted (int fd, int cmd, void *arg) + attribute_hidden; +extern int __libc_fcntl64 (int fd, int cmd, ...); +libc_hidden_proto (__libc_fcntl64) extern int __open (const char *__file, int __oflag, ...); libc_hidden_proto (__open) extern int __fcntl (int __fd, int __cmd, ...); libc_hidden_proto (__fcntl) +extern int __fcntl64 (int __fd, int __cmd, ...) attribute_hidden; +libc_hidden_proto (__fcntl64) extern int __openat (int __fd, const char *__file, int __oflag, ...) __nonnull ((2)); libc_hidden_proto (__openat) diff --git a/io/Makefile b/io/Makefile index 2117cb6b62b..4a0d8fea092 100644 --- a/io/Makefile +++ b/io/Makefile @@ -40,7 +40,7 @@ routines := \ mkdir mkdirat \ open open_2 open64 open64_2 openat openat_2 openat64 openat64_2 \ read write lseek lseek64 access euidaccess faccessat \ - fcntl flock lockf lockf64 \ + fcntl fcntl64 flock lockf lockf64 \ close dup dup2 dup3 pipe pipe2 \ creat creat64 \ chdir fchdir \ @@ -89,6 +89,7 @@ CFLAGS-open64.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-creat.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-creat64.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-fcntl.c += -fexceptions -fasynchronous-unwind-tables +CFLAGS-fcntl64.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-poll.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-ppoll.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-lockf.c += -fexceptions diff --git a/io/Versions b/io/Versions index 4448b7197c4..98037fbbfcc 100644 --- a/io/Versions +++ b/io/Versions @@ -128,8 +128,11 @@ libc { GLIBC_2.27 { copy_file_range; } + GLIBC_2.28 { + fcntl64; + } GLIBC_PRIVATE { - __libc_fcntl; + __libc_fcntl64; __fcntl_nocancel; __open64_nocancel; __write_nocancel; diff --git a/io/fcntl.h b/io/fcntl.h index 69a4394191b..3afc62011a2 100644 --- a/io/fcntl.h +++ b/io/fcntl.h @@ -167,7 +167,18 @@ typedef __pid_t pid_t; This function is a cancellation point and therefore not marked with __THROW. */ +#ifndef __USE_FILE_OFFSET64 extern int fcntl (int __fd, int __cmd, ...); +#else +# ifdef __REDIRECT +extern int __REDIRECT (fcntl, (int __fd, int __cmd, ...), fcntl64); +# else +# define fcntl fcntl64 +# endif +#endif +#ifdef __USE_LARGEFILE64 +extern int fcntl64 (int __fd, int __cmd, ...); +#endif /* Open FILE and return a new file descriptor for it, or -1 on error. OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set diff --git a/io/fcntl64.c b/io/fcntl64.c new file mode 100644 index 00000000000..f4e6809abc2 --- /dev/null +++ b/io/fcntl64.c @@ -0,0 +1,38 @@ +/* Manipulate file descriptor. Stub LFS version. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +/* Perform file control operations on FD. */ +int +__fcntl64 (int fd, int cmd, ...) +{ + if (fd < 0) + { + __set_errno (EBADF); + return -1; + } + + __set_errno (ENOSYS); + return -1; +} +libc_hidden_def (__fcntl64) +stub_warning (fcntl64) + +weak_alias (__fcntl64, fcntl64) diff --git a/login/utmp_file.c b/login/utmp_file.c index 72dd21387c2..040a5057116 100644 --- a/login/utmp_file.c +++ b/login/utmp_file.c @@ -82,7 +82,7 @@ static void timeout_handler (int signum) {}; memset (&fl, '\0', sizeof (struct flock)); \ fl.l_type = (type); \ fl.l_whence = SEEK_SET; \ - if (__fcntl_nocancel ((fd), F_SETLKW, &fl) < 0) + if (__fcntl64_nocancel ((fd), F_SETLKW, &fl) < 0) #define LOCKING_FAILED() \ goto unalarm_return @@ -90,7 +90,7 @@ static void timeout_handler (int signum) {}; #define UNLOCK_FILE(fd) \ /* Unlock the file. */ \ fl.l_type = F_UNLCK; \ - __fcntl_nocancel ((fd), F_SETLKW, &fl); \ + __fcntl64_nocancel ((fd), F_SETLKW, &fl); \ \ unalarm_return: \ /* Reset the signal handler and alarm. We must reset the alarm \ diff --git a/manual/llio.texi b/manual/llio.texi index 82f03be2be1..e840c55f860 100644 --- a/manual/llio.texi +++ b/manual/llio.texi @@ -3281,12 +3281,13 @@ Set process or process group ID to receive @code{SIGIO} signals. @xref{Interrupt Input}. @end vtable -This function is a cancellation point in multi-threaded programs. This -is a problem if the thread allocates some resources (like memory, file -descriptors, semaphores or whatever) at the time @code{fcntl} is -called. If the thread gets canceled these resources stay allocated -until the program ends. To avoid this calls to @code{fcntl} should be -protected using cancellation handlers. +This function is a cancellation point in multi-threaded programs for the +commands @code{F_SETLKW} (and the LFS analogous @code{F_SETLKW64}) and +@code {F_OFD_SETLKW}. This is a problem if the thread allocates some +resources (like memory, file descriptors, semaphores or whatever) at the time +@code{fcntl} is called. If the thread gets canceled these resources stay +allocated until the program ends. To avoid this calls to @code{fcntl} should +be protected using cancellation handlers. @c ref pthread_cleanup_push / pthread_cleanup_pop @end deftypefun diff --git a/nptl/Makefile b/nptl/Makefile index 6cfc8c60ee5..0f9c44afa02 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -191,6 +191,7 @@ CFLAGS-sem_timedwait.c += -fexceptions -fasynchronous-unwind-tables # These are the function wrappers we have to duplicate here. CFLAGS-fcntl.c += -fexceptions -fasynchronous-unwind-tables +CFLAGS-fcntl64.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-lockf.c += -fexceptions CFLAGS-pread.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-pread64.c += -fexceptions -fasynchronous-unwind-tables diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h index 19ad8cbc4c4..d9f8a75dbda 100644 --- a/sysdeps/generic/not-cancel.h +++ b/sysdeps/generic/not-cancel.h @@ -51,7 +51,7 @@ __pause () #define __nanosleep_nocancel(requested_time, remaining) \ __nanosleep (requested_time, remaining) -#define __fcntl_nocancel(fd, cmd, ...) \ - __fcntl (fd, cmd, __VA_ARGS__) +#define __fcntl64_nocancel(fd, cmd, ...) \ + __fcntl64 (fd, cmd, __VA_ARGS__) #endif /* NOT_CANCEL_H */ diff --git a/sysdeps/mach/hurd/bits/errno.h b/sysdeps/mach/hurd/bits/errno.h index 8096fb9c05d..bb8b8b669f0 100644 --- a/sysdeps/mach/hurd/bits/errno.h +++ b/sysdeps/mach/hurd/bits/errno.h @@ -1,9 +1,18 @@ /* This file generated by errnos.awk from errno.texi + stdc-predef.h + libc-symbols.h mach/message.h mach/kern_return.h + mach/i386/kern_return.h + mach/port.h + mach/boolean.h + mach/i386/boolean.h + mach/i386/vm_types.h mach/mig_errors.h device/device_types.h + mach/std_types.h + /home/azanella/Projects/glibc/build/i686-gnu/errnos.d Do not edit this file; edit errnos.awk and regenerate it. */ #ifndef _BITS_ERRNO_H diff --git a/sysdeps/mach/hurd/fcntl.c b/sysdeps/mach/hurd/fcntl.c index 0b231645c51..598317d811e 100644 --- a/sysdeps/mach/hurd/fcntl.c +++ b/sysdeps/mach/hurd/fcntl.c @@ -210,3 +210,8 @@ libc_hidden_def (__libc_fcntl) weak_alias (__libc_fcntl, __fcntl) libc_hidden_weak (__fcntl) weak_alias (__libc_fcntl, fcntl) + +strong_alias (__libc_fcntl, __libc_fcntl64) +libc_hidden_def (__libc_fcntl64) +weak_alias (__libc_fcntl64, __fcntl64) +libc_hidden_weak (__fcntl64) diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index 2cb507052bd..3d46de795d9 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2033,6 +2033,8 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/posix/fdopendir.c b/sysdeps/posix/fdopendir.c index dafb5d20c10..b72eecc66b5 100644 --- a/sysdeps/posix/fdopendir.c +++ b/sysdeps/posix/fdopendir.c @@ -38,7 +38,7 @@ __fdopendir (int fd) } /* Make sure the descriptor allows for reading. */ - int flags = __fcntl_nocancel (fd, F_GETFL); + int flags = __fcntl64_nocancel (fd, F_GETFL); if (__glibc_unlikely (flags == -1)) return NULL; if (__glibc_unlikely ((flags & O_ACCMODE) == O_WRONLY)) diff --git a/sysdeps/posix/opendir.c b/sysdeps/posix/opendir.c index 0875385f652..bb6bd7cc853 100644 --- a/sysdeps/posix/opendir.c +++ b/sysdeps/posix/opendir.c @@ -99,7 +99,7 @@ __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp) /* We have to set the close-on-exit flag if the user provided the file descriptor. */ if (!close_fd - && __glibc_unlikely (__fcntl_nocancel (fd, F_SETFD, FD_CLOEXEC) < 0)) + && __glibc_unlikely (__fcntl64_nocancel (fd, F_SETFD, FD_CLOEXEC) < 0)) goto lose; const size_t default_allocation = (4 * BUFSIZ < sizeof (struct dirent64) diff --git a/sysdeps/unix/pt-fcntl.c b/sysdeps/unix/pt-fcntl.c index 8113d52b86a..3d64054dd0d 100644 --- a/sysdeps/unix/pt-fcntl.c +++ b/sysdeps/unix/pt-fcntl.c @@ -37,7 +37,7 @@ fcntl_compat (int fd, int cmd, ...) va_start (ap, cmd); arg = va_arg (ap, void *); va_end (ap); - return __libc_fcntl (fd, cmd, arg); + return __libc_fcntl64 (fd, cmd, arg); } weak_alias (fcntl_compat, fcntl_alias) diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 215fd5d1368..f71cc39c7e2 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -45,7 +45,9 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \ - tst-rlimit-infinity + tst-rlimit-infinity tst-ofdlocks +tests-internal += tst-ofdlocks-compat + # Generate the list of SYS_* macros for the system calls (__NR_* # macros). The file syscall-names.list contains all possible system diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 80cdb98e1ca..884d0dfa95c 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2131,3 +2131,4 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl64 F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index c761f61c435..28d54b97949 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2026,6 +2026,7 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist index 6aa58c3ca71..dfde3bd7258 100644 --- a/sysdeps/unix/sysv/linux/arm/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist @@ -115,6 +115,8 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/fcntl.c b/sysdeps/unix/sysv/linux/fcntl.c index e3992dc9d4d..cbab7b401a3 100644 --- a/sysdeps/unix/sysv/linux/fcntl.c +++ b/sysdeps/unix/sysv/linux/fcntl.c @@ -20,15 +20,12 @@ #include #include #include -#include -#ifndef __NR_fcntl64 -# define __NR_fcntl64 __NR_fcntl -#endif +#ifndef __OFF_T_MATCHES_OFF64_T -#ifndef FCNTL_ADJUST_CMD -# define FCNTL_ADJUST_CMD(__cmd) __cmd -#endif +# ifndef FCNTL_ADJUST_CMD +# define FCNTL_ADJUST_CMD(__cmd) __cmd +# endif int __libc_fcntl (int fd, int cmd, ...) @@ -42,13 +39,84 @@ __libc_fcntl (int fd, int cmd, ...) cmd = FCNTL_ADJUST_CMD (cmd); - if (cmd == F_SETLKW || cmd == F_SETLKW64) - return SYSCALL_CANCEL (fcntl64, fd, cmd, (void *) arg); - - return __fcntl_nocancel_adjusted (fd, cmd, arg); + switch (cmd) + { + case F_SETLKW: + case F_SETLKW64: + return SYSCALL_CANCEL (fcntl64, fd, cmd, arg); + case F_OFD_SETLKW: + { + struct flock *flk = (struct flock *) arg; + struct flock64 flk64 = + { + .l_type = flk->l_type, + .l_whence = flk->l_whence, + .l_start = flk->l_start, + .l_len = flk->l_len, + .l_pid = flk->l_pid + }; + return SYSCALL_CANCEL (fcntl64, fd, cmd, &flk64); + } + case F_OFD_GETLK: + case F_OFD_SETLK: + { + struct flock *flk = (struct flock *) arg; + struct flock64 flk64 = + { + .l_type = flk->l_type, + .l_whence = flk->l_whence, + .l_start = flk->l_start, + .l_len = flk->l_len, + .l_pid = flk->l_pid + }; + int ret = INLINE_SYSCALL_CALL (fcntl64, fd, cmd, &flk64); + if (ret == -1) + return -1; + if ((off_t) flk64.l_start != flk64.l_start + || (off_t) flk64.l_len != flk64.l_len) + { + __set_errno (EOVERFLOW); + return -1; + } + flk->l_type = flk64.l_type; + flk->l_whence = flk64.l_whence; + flk->l_start = flk64.l_start; + flk->l_len = flk64.l_len; + flk->l_pid = flk64.l_pid; + return ret; + } + /* Since only F_SETLKW{64}/F_OLD_SETLK are cancellation entrypoints and + only OFD locks require LFS handling, all others flags are handled + unmodified by calling __NR_fcntl64. */ + default: + return __fcntl64_nocancel_adjusted (fd, cmd, arg); + } } libc_hidden_def (__libc_fcntl) weak_alias (__libc_fcntl, __fcntl) libc_hidden_weak (__fcntl) + +# include +# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_28) +int +__old_libc_fcntl64 (int fd, int cmd, ...) +{ + va_list ap; + void *arg; + + va_start (ap, cmd); + arg = va_arg (ap, void *); + va_end (ap); + + /* Previous versions called __NR_fcntl64 for fcntl (which did not handle + OFD locks in LFS mode). */ + return __libc_fcntl64 (fd, cmd, arg); +} +compat_symbol (libc, __old_libc_fcntl64, fcntl, GLIBC_2_0); +versioned_symbol (libc, __libc_fcntl, fcntl, GLIBC_2_28); +# else weak_alias (__libc_fcntl, fcntl) +# endif + +#endif /* __OFF_T_MATCHES_OFF64_T */ diff --git a/sysdeps/unix/sysv/linux/fcntl64.c b/sysdeps/unix/sysv/linux/fcntl64.c new file mode 100644 index 00000000000..f21667ae43a --- /dev/null +++ b/sysdeps/unix/sysv/linux/fcntl64.c @@ -0,0 +1,63 @@ +/* Manipulate file descriptor. Linux LFS version. + Copyright (C) 2018 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 + . */ + +#define fcntl __no_decl_fcntl +#define __fcntl __no_decl___fcntl +#include +#undef fcntl +#undef __fcntl +#include +#include +#include + +#ifndef __NR_fcntl64 +# define __NR_fcntl64 __NR_fcntl +#endif + +#ifndef FCNTL_ADJUST_CMD +# define FCNTL_ADJUST_CMD(__cmd) __cmd +#endif + +int +__libc_fcntl64 (int fd, int cmd, ...) +{ + va_list ap; + void *arg; + + va_start (ap, cmd); + arg = va_arg (ap, void *); + va_end (ap); + + cmd = FCNTL_ADJUST_CMD (cmd); + + if (cmd == F_SETLKW || cmd == F_SETLKW64 || cmd == F_OFD_SETLKW) + return SYSCALL_CANCEL (fcntl64, fd, cmd, arg); + + return __fcntl64_nocancel_adjusted (fd, cmd, arg); +} +libc_hidden_def (__libc_fcntl64) +weak_alias (__libc_fcntl64, __fcntl64) +libc_hidden_weak (__fcntl64) +weak_alias (__libc_fcntl64, fcntl64) + +#ifdef __OFF_T_MATCHES_OFF64_T +weak_alias (__libc_fcntl64, __libc_fcntl) +weak_alias (__libc_fcntl64, __fcntl) +weak_alias (__libc_fcntl64, __GI___fcntl) +weak_alias (__libc_fcntl64, fcntl) +#endif diff --git a/sysdeps/unix/sysv/linux/fcntl_nocancel.c b/sysdeps/unix/sysv/linux/fcntl_nocancel.c index f50e382c4a1..dd336b56796 100644 --- a/sysdeps/unix/sysv/linux/fcntl_nocancel.c +++ b/sysdeps/unix/sysv/linux/fcntl_nocancel.c @@ -31,7 +31,7 @@ #endif int -__fcntl_nocancel (int fd, int cmd, ...) +__fcntl64_nocancel (int fd, int cmd, ...) { va_list ap; void *arg; @@ -42,12 +42,12 @@ __fcntl_nocancel (int fd, int cmd, ...) cmd = FCNTL_ADJUST_CMD (cmd); - return __fcntl_nocancel_adjusted (fd, cmd, arg); + return __fcntl64_nocancel_adjusted (fd, cmd, arg); } -hidden_def (__fcntl_nocancel) +hidden_def (__fcntl64_nocancel) int -__fcntl_nocancel_adjusted (int fd, int cmd, void *arg) +__fcntl64_nocancel_adjusted (int fd, int cmd, void *arg) { if (cmd == F_GETOWN) { diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index d10695b7d3c..06b00f730a7 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -1872,6 +1872,8 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 23092ab6d7e..1c1cc00d402 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2037,6 +2037,8 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 7bf259e86c8..f6e17a005f6 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -1907,6 +1907,7 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 4673bcd79b4..ee054a618d3 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -116,6 +116,8 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 GLIBC_2.4 _IO_2_1_stdin_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index 1f8ac403991..227a0581cbf 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -1981,6 +1981,8 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist index 09277f59548..18781b30171 100644 --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist @@ -2122,3 +2122,5 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index f562e20f23f..2d86989cf26 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -1959,6 +1959,8 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index ceb7388829c..b8b113e1a50 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -1957,6 +1957,8 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 5765f487a2a..6a3cd13e2d8 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -1965,6 +1965,8 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index a84bb45a386..596ec05379f 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -1961,6 +1961,7 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index e43295986c2..8da18eed574 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2163,3 +2163,5 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h index 0b5c9559899..09de92dee94 100644 --- a/sysdeps/unix/sysv/linux/not-cancel.h +++ b/sysdeps/unix/sysv/linux/not-cancel.h @@ -76,7 +76,7 @@ __typeof (pause) __pause_nocancel; __typeof (__nanosleep) __nanosleep_nocancel; /* Uncancelable fcntl. */ -__typeof (__fcntl) __fcntl_nocancel; +__typeof (__fcntl) __fcntl64_nocancel; #if IS_IN (libc) || IS_IN (rtld) hidden_proto (__open_nocancel) @@ -89,7 +89,7 @@ hidden_proto (__close_nocancel) hidden_proto (__waitpid_nocancel) hidden_proto (__pause_nocancel) hidden_proto (__nanosleep_nocancel) -hidden_proto (__fcntl_nocancel) +hidden_proto (__fcntl64_nocancel) #endif #endif /* NOT_CANCEL_H */ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index a5f2b230683..555751eb12a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -1985,6 +1985,8 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index e4cbe362794..80324e41aab 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -1989,6 +1989,8 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist index 9869feb56b4..97b1d354afc 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist @@ -2221,3 +2221,4 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl64 F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist index e526dc4627b..15be314921b 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist @@ -116,6 +116,7 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl64 F GLIBC_2.3 _Exit F GLIBC_2.3 _IO_2_1_stderr_ D 0xe0 GLIBC_2.3 _IO_2_1_stdin_ D 0xe0 diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index e6319eef8d4..436b9922512 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2093,3 +2093,4 @@ GLIBC_2.27 xdrstdio_create F GLIBC_2.27 xencrypt F GLIBC_2.27 xprt_register F GLIBC_2.27 xprt_unregister F +GLIBC_2.28 fcntl64 F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 41cdda0c2ef..f66715f0c95 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -1994,6 +1994,8 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 8a756cf2875..bd6242861b4 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -1900,6 +1900,7 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist index 999bddd1db9..f2f070fbcee 100644 --- a/sysdeps/unix/sysv/linux/sh/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist @@ -1876,6 +1876,8 @@ GLIBC_2.27 wcstof32x F GLIBC_2.27 wcstof32x_l F GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 7c4296fc10b..265087f6a81 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -1988,6 +1988,8 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index dafe9d74b7c..16a69812cbc 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -1930,6 +1930,7 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/tst-ofdlocks-compat.c b/sysdeps/unix/sysv/linux/tst-ofdlocks-compat.c new file mode 100644 index 00000000000..d1d00eb3fb9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-ofdlocks-compat.c @@ -0,0 +1,84 @@ +/* Check non representable OFD locks regions in non-LFS mode for compat + mode (BZ #20251) + Copyright (C) 2018 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include +#include + +#include +#include + +#include +#if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_28) +compat_symbol_reference (libc, fcntl, fcntl, GLIBC_2_0); + +static char *temp_filename; +static int temp_fd; + +static void +do_prepare (int argc, char **argv) +{ + temp_fd = create_temp_file ("tst-ofdlocks-compat.", &temp_filename); + TEST_VERIFY_EXIT (temp_fd != -1); +} + +#define PREPARE do_prepare + +static int +do_test (void) +{ + /* The compat fcntl version for architectures which support non-LFS + operations does not wrap the flock OFD argument, so the struct is passed + unmodified to kernel. It means no EOVERFLOW is returned, so operations + with LFS should not incur in failure. */ + + struct flock64 lck64 = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = (off64_t)INT32_MAX + 1024, + .l_len = 1024, + }; + TEST_VERIFY_EXIT (fcntl (temp_fd, F_OFD_SETLKW, &lck64) == 0); + + /* Open file description locks placed through the same open file description + (either by same file descriptor or a duplicated one created by fork, + dup, fcntl F_DUPFD, etc.) overwrites then old lock. To force a + conflicting lock combination, it creates a new file descriptor. */ + int fd = open64 (temp_filename, O_RDWR, 0666); + TEST_VERIFY_EXIT (fd != -1); + + struct flock64 lck = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = INT32_MAX - 1024, + .l_len = 4 * 1024, + }; + TEST_VERIFY (fcntl (fd, F_OFD_GETLK, &lck) == 0); + + return 0; +} +#else +static int +do_test (void) +{ + return 77; +} +#endif + +#include diff --git a/sysdeps/unix/sysv/linux/tst-ofdlocks.c b/sysdeps/unix/sysv/linux/tst-ofdlocks.c new file mode 100644 index 00000000000..bd345e9b649 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-ofdlocks.c @@ -0,0 +1,76 @@ +/* Check non representable OFD locks regions in non-LFS mode (BZ #20251) + Copyright (C) 2018 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include +#include +#include +#include + +#include +#include + +static char *temp_filename; +static int temp_fd; + +static void +do_prepare (int argc, char **argv) +{ + temp_fd = create_temp_file ("tst-ofdlocks.", &temp_filename); + TEST_VERIFY_EXIT (temp_fd != -1); +} + +#define PREPARE do_prepare + +static int +do_test (void) +{ + /* It first allocates a open file description lock range which can not + be represented in a 32 bit struct flock. */ + struct flock64 lck64 = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = (off64_t)INT32_MAX + 1024, + .l_len = 1024, + }; + TEST_VERIFY_EXIT (fcntl64 (temp_fd, F_OFD_SETLKW, &lck64) == 0); + + /* Open file description locks placed through the same open file description + (either by same file descriptor or a duplicated one created by fork, + dup, fcntl F_DUPFD, etc.) overwrites then old lock. To force a + conflicting lock combination, it creates a new file descriptor. */ + int fd = open64 (temp_filename, O_RDWR, 0666); + TEST_VERIFY_EXIT (fd != -1); + + /* It tries then to allocate another open file descriptior with a valid + non-LFS bits struct flock but which will result in a conflicted region + which can not be represented in a non-LFS struct flock. */ + struct flock lck = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = INT32_MAX - 1024, + .l_len = 4 * 1024, + }; + int r = fcntl (fd, F_OFD_GETLK, &lck); + if (sizeof (off_t) != sizeof (off64_t)) + TEST_VERIFY (r == -1 && errno == EOVERFLOW); + else + TEST_VERIFY (r == 0); + + return 0; +} + +#include diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index f72d4949204..fa8c198d135 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -1888,6 +1888,7 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl64 F GLIBC_2.3 __ctype_b_loc F GLIBC_2.3 __ctype_tolower_loc F GLIBC_2.3 __ctype_toupper_loc F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 96c9fa050e9..2536971682a 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2139,3 +2139,4 @@ GLIBC_2.27 wcstof64 F GLIBC_2.27 wcstof64_l F GLIBC_2.27 wcstof64x F GLIBC_2.27 wcstof64x_l F +GLIBC_2.28 fcntl64 F