From d2129ad4570455d418b3ca34eeffd0505df088ea Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 20 Mar 2016 17:56:47 +0100 Subject: hurd: Do not hide rtld symbols which need to be preempted * sysdeps/generic/dl-fcntl.h: New file, adds attribute_hidden to __open and __fcntl. * sysdeps/mach/hurd/dl-fcntl.h: New file, adds attribute_hidden to __fcntl only. * include/fcntl.h [IS_IN (rtld)]: Include instead of adding attribute_hidden to __open and __fcntl. --- include/fcntl.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/fcntl.h') diff --git a/include/fcntl.h b/include/fcntl.h index 4168ee429f..3b2c887146 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -31,8 +31,7 @@ extern int __openat64_2 (int __fd, const char *__path, int __oflag); #if IS_IN (rtld) -extern __typeof (__open) __open attribute_hidden; -extern __typeof (__fcntl) __fcntl attribute_hidden; +# include #endif /* Flag determining whether the *at system calls are available. */ -- cgit v1.2.3 From cef9b65376a044309f74b77860ccf3c48a4ae315 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Tue, 18 Apr 2017 14:56:51 +0200 Subject: Assume that O_CLOEXEC is always defined and works --- ChangeLog | 56 ++++++++++++++++++++++++++ elf/dl-misc.c | 6 +-- include/fcntl.h | 4 -- io/Makefile | 2 - io/have_o_cloexec.c | 23 ----------- libio/fileops.c | 16 -------- libio/iopopen.c | 2 - login/utmp_file.c | 65 ++----------------------------- malloc/mtrace.c | 9 ----- nis/nss_compat/compat-grp.c | 52 +------------------------ nis/nss_compat/compat-initgroups.c | 52 +------------------------ nis/nss_compat/compat-pwd.c | 52 +------------------------ nis/nss_compat/compat-spwd.c | 52 +------------------------ nscd/connections.c | 37 +++--------------- nss/Makefile | 2 +- nss/nss_db/db-open.c | 6 +-- nss/nss_files/files-XXX.c | 35 ----------------- nss/nss_files/files-alias.c | 35 ----------------- nss/nss_files/files-have_o_cloexec.c | 23 ----------- posix/wordexp.c | 8 +--- shadow/lckpwdf.c | 29 +------------- sysdeps/mach/hurd/kernel-features.h | 1 - sysdeps/nacl/kernel-features.h | 2 - sysdeps/posix/getcwd.c | 8 +--- sysdeps/posix/opendir.c | 47 +++++----------------- sysdeps/posix/shm_open.c | 28 +------------ sysdeps/unix/sysv/linux/kernel-features.h | 4 -- 27 files changed, 91 insertions(+), 565 deletions(-) delete mode 100644 io/have_o_cloexec.c delete mode 100644 nss/nss_files/files-have_o_cloexec.c (limited to 'include/fcntl.h') diff --git a/ChangeLog b/ChangeLog index 3a8ea7d303..ce6f13d179 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,59 @@ +2017-04-18 Florian Weimer + + * elf/dl-misc.c (_dl_sysdep_read_whole_file): Assume that + O_CLOEXEC is defined. + * include/fcntl.h (__have_o_cloexec): Remove declaration. + * io/Makefile (aux): Remove. + * io/have_o_cloexec.c: Remove file. + * libio/fileops.c (_IO_new_file_fopen): Assume that O_CLOEXEC is + defined and works. + * libio/iopopen.c (_IO_new_proc_open): Assume that O_CLOEXEC is + defined. + * login/utmp_file.c (O_flags): Remove definition. + (setutent_file): Use O_CLOEXEC instead of O_flags. Assume that + O_CLOEXEC works. + (pututline_file): Likewise. + * malloc/mtrace.c: Assume that O_CLOEXEC works. + * nis/nss_compat/compat-grp.c (__compat_have_cloexec): Remove + definition. + (internal_setgrent): Assume that O_CLOEXEC works. + * nis/nss_compat/compat-initgroups.c (__compat_have_cloexec): + Remove definition. + (internal_setgrent): Assume that O_CLOEXEC works. + * nis/nss_compat/compat-pwd.c (__compat_have_cloexec): Remove + definition. + (internal_setpwent): Assume that O_CLOEXEC works. + * nis/nss_compat/compat-spwd.c (__compat_have_cloexec): Remove + definition. + (internal_setspent): Assume that O_CLOEXEC works. + * nscd/connections.c (EXTRA_O_FLAGS): Remove definition. + (nscd_init): Use O_CLOEXEC instead of EXTRA_O_FLAGS. Assume that + O_CLOEXEC is defined and works. + * nss/Makefile (libnss_files-routines): Remove + files-have_o_cloexec. + * nss/nss_db/db-open.c (internal_setent): Assume that O_CLOEXEC is + defined. + * nss/nss_files/files-XXX.c (internal_setent): Assume that + O_CLOEXEC is defined and works. + * nss/nss_files/files-alias.c (internal_setent): Likewise. + * nss/nss_files/files-have_o_cloexec.c: Remove. + * posix/wordexp.c (exec_comm_child): Assume that O_CLOEXEC is + defined. + * shadow/lckpwdf.c (__lckpwdf): Assume that O_CLOEXEC is defined + and works. + * sysdeps/mach/hurd/kernel-features.h (__ASSUME_O_CLOEXEC): Remove + definition. + * sysdeps/nacl/kernel-features.h (__ASSUME_O_CLOEXEC): Likewise. + * sysdeps/posix/getcwd.c (__getcwd): Assume that O_CLOEXEC works. + * sysdeps/posix/opendir.c (opendir_oflags): Turn into enum constant. + (__opendirat, __opendir): Adjust opendir_oflags call. + (check_have_o_cloexec): Remove. + (__alloc_dir): Assume that O_CLOEXEC is defined and works. + * sysdeps/posix/shm_open.c (shm_open): Assume that O_CLOEXEC is + defined. + * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_O_CLOEXEC): + Remove definition. + 2017-04-18 Florian Weimer * include/unistd.h (__have_dup3): Remove declaration. diff --git a/elf/dl-misc.c b/elf/dl-misc.c index 1e9a6ee560..c5d3e0e7c5 100644 --- a/elf/dl-misc.c +++ b/elf/dl-misc.c @@ -45,11 +45,7 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) { void *result = MAP_FAILED; struct stat64 st; - int flags = O_RDONLY; -#ifdef O_CLOEXEC - flags |= O_CLOEXEC; -#endif - int fd = __open (file, flags); + int fd = __open (file, O_RDONLY | O_CLOEXEC); if (fd >= 0) { if (__fxstat64 (_STAT_VER, fd, &st) >= 0) diff --git a/include/fcntl.h b/include/fcntl.h index 3b2c887146..9a007c358c 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -36,10 +36,6 @@ extern int __openat64_2 (int __fd, const char *__path, int __oflag); /* Flag determining whether the *at system calls are available. */ extern int __have_atfcts attribute_hidden; - -#ifdef O_CLOEXEC -extern int __have_o_cloexec attribute_hidden; -#endif #endif #endif diff --git a/io/Makefile b/io/Makefile index 333a049d2b..95e04b241b 100644 --- a/io/Makefile +++ b/io/Makefile @@ -55,8 +55,6 @@ routines := \ sendfile sendfile64 \ utimensat futimens -aux := have_o_cloexec - # These routines will be omitted from the libc shared object. # Instead the static object files will be included in a special archive # linked against when the shared library will be used. diff --git a/io/have_o_cloexec.c b/io/have_o_cloexec.c deleted file mode 100644 index 295ecccb77..0000000000 --- a/io/have_o_cloexec.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2007-2017 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 - -#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC -int __have_o_cloexec; -#endif diff --git a/libio/fileops.c b/libio/fileops.c index f12ed16e30..c55e196dd8 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -321,9 +321,7 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode, fp->_flags2 |= _IO_FLAGS2_NOTCANCEL; continue; case 'e': -#ifdef O_CLOEXEC oflags |= O_CLOEXEC; -#endif fp->_flags2 |= _IO_FLAGS2_CLOEXEC; continue; default: @@ -338,20 +336,6 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode, if (result != NULL) { -#ifndef __ASSUME_O_CLOEXEC - if ((fp->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 && __have_o_cloexec <= 0) - { - int fd = _IO_fileno (fp); - if (__have_o_cloexec == 0) - { - int flags = __fcntl (fd, F_GETFD); - __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1; - } - if (__have_o_cloexec < 0) - __fcntl (fd, F_SETFD, FD_CLOEXEC); - } -#endif - /* Test whether the mode string specifies the conversion. */ cs = strstr (last_recognized + 1, ",ccs="); if (cs != NULL) diff --git a/libio/iopopen.c b/libio/iopopen.c index 95a12c90b5..b78e7e5ef2 100644 --- a/libio/iopopen.c +++ b/libio/iopopen.c @@ -173,12 +173,10 @@ _IO_new_proc_open (_IO_FILE *fp, const char *command, const char *mode) if (child_end != child_std_end) _IO_dup2 (child_end, child_std_end); -#ifdef O_CLOEXEC else /* The descriptor is already the one we will use. But it must not be marked close-on-exec. Undo the effects. */ __fcntl (child_end, F_SETFD, 0); -#endif /* POSIX.2: "popen() shall ensure that any streams from previous popen() calls that remain open in the parent process are closed in the new child process." */ diff --git a/login/utmp_file.c b/login/utmp_file.c index b1dfb3f644..6ebe1ef123 100644 --- a/login/utmp_file.c +++ b/login/utmp_file.c @@ -141,42 +141,11 @@ setutent_file (void) file_name = TRANSFORM_UTMP_FILE_NAME (__libc_utmp_file_name); -#ifdef O_CLOEXEC -# define O_flags O_LARGEFILE | O_CLOEXEC -#else -# define O_flags O_LARGEFILE -#endif file_writable = false; - file_fd = open_not_cancel_2 (file_name, O_RDONLY | O_flags); + file_fd = open_not_cancel_2 + (file_name, O_RDONLY | O_LARGEFILE | O_CLOEXEC); if (file_fd == -1) return 0; - -#ifndef __ASSUME_O_CLOEXEC -# ifdef O_CLOEXEC - if (__have_o_cloexec <= 0) -# endif - { - /* We have to make sure the file is `closed on exec'. */ - int result = fcntl_not_cancel (file_fd, F_GETFD, 0); - if (result >= 0) - { -# ifdef O_CLOEXEC - if (__have_o_cloexec == 0) - __have_o_cloexec = (result & FD_CLOEXEC) ? 1 : -1; - - if (__have_o_cloexec < 0) -# endif - result = fcntl_not_cancel (file_fd, F_SETFD, - result | FD_CLOEXEC); - } - - if (result == -1) - { - close_not_cancel_no_status (file_fd); - return 0; - } - } -#endif } __lseek64 (file_fd, 0, SEEK_SET); @@ -404,37 +373,11 @@ pututline_file (const struct utmp *data) /* We must make the file descriptor writable before going on. */ const char *file_name = TRANSFORM_UTMP_FILE_NAME (__libc_utmp_file_name); - int new_fd = open_not_cancel_2 (file_name, O_RDWR | O_flags); + int new_fd = open_not_cancel_2 + (file_name, O_RDWR | O_LARGEFILE | O_CLOEXEC); if (new_fd == -1) return NULL; -#ifndef __ASSUME_O_CLOEXEC -# ifdef O_CLOEXEC - if (__have_o_cloexec <= 0) -# endif - { - /* We have to make sure the file is `closed on exec'. */ - int result = fcntl_not_cancel (file_fd, F_GETFD, 0); - if (result >= 0) - { -# ifdef O_CLOEXEC - if (__have_o_cloexec == 0) - __have_o_cloexec = (result & FD_CLOEXEC) ? 1 : -1; - - if (__have_o_cloexec < 0) -# endif - result = fcntl_not_cancel (file_fd, F_SETFD, - result | FD_CLOEXEC); - } - - if (result == -1) - { - close_not_cancel_no_status (file_fd); - return NULL; - } - } -#endif - if (__lseek64 (new_fd, __lseek64 (file_fd, 0, SEEK_CUR), SEEK_SET) == -1 || __dup2 (new_fd, file_fd) < 0) { diff --git a/malloc/mtrace.c b/malloc/mtrace.c index 800f2a827a..02c53eb9fe 100644 --- a/malloc/mtrace.c +++ b/malloc/mtrace.c @@ -300,15 +300,6 @@ mtrace (void) mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "wce"); if (mallstream != NULL) { -#ifndef __ASSUME_O_CLOEXEC - /* Make sure we close the file descriptor on exec. */ - int flags = __fcntl (fileno (mallstream), F_GETFD, 0); - if (flags >= 0) - { - flags |= FD_CLOEXEC; - __fcntl (fileno (mallstream), F_SETFD, flags); - } -#endif /* Be sure it doesn't malloc its buffer! */ malloc_trace_buffer = mtb; setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE); diff --git a/nis/nss_compat/compat-grp.c b/nis/nss_compat/compat-grp.c index e830a2f0a2..0381458c0c 100644 --- a/nis/nss_compat/compat-grp.c +++ b/nis/nss_compat/compat-grp.c @@ -70,19 +70,6 @@ static ent_t ext_ent = { TRUE, NSS_STATUS_SUCCESS, NULL, { NULL, 0, 0 }}; /* Protect global state against multiple changers. */ __libc_lock_define_initialized (static, lock) -/* Positive if O_CLOEXEC is supported, negative if it is not supported, - zero if it is still undecided. This variable is shared with the - other compat functions. */ -#ifdef __ASSUME_O_CLOEXEC -# define __compat_have_cloexec 1 -#else -# ifdef O_CLOEXEC -int __compat_have_cloexec; -# else -# define __compat_have_cloexec -1 -# endif -#endif - /* Prototypes for local functions. */ static void blacklist_store_name (const char *, ent_t *); static int in_blacklist (const char *, int, ent_t *); @@ -125,43 +112,8 @@ internal_setgrent (ent_t *ent, int stayopen, int needent) if (ent->stream == NULL) status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; else - { - /* We have to make sure the file is `closed on exec'. */ - int result = 0; - - if (__compat_have_cloexec <= 0) - { - int flags; - result = flags = fcntl (fileno_unlocked (ent->stream), F_GETFD, - 0); - if (result >= 0) - { -#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC - if (__compat_have_cloexec == 0) - __compat_have_cloexec = (flags & FD_CLOEXEC) ? 1 : -1; - - if (__compat_have_cloexec < 0) -#endif - { - flags |= FD_CLOEXEC; - result = fcntl (fileno_unlocked (ent->stream), F_SETFD, - flags); - } - } - } - - if (result < 0) - { - /* Something went wrong. Close the stream and return a - failure. */ - fclose (ent->stream); - ent->stream = NULL; - status = NSS_STATUS_UNAVAIL; - } - else - /* We take care of locking ourself. */ - __fsetlocking (ent->stream, FSETLOCKING_BYCALLER); - } + /* We take care of locking ourself. */ + __fsetlocking (ent->stream, FSETLOCKING_BYCALLER); } else rewind (ent->stream); diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c index 1b37e0c295..795213448c 100644 --- a/nis/nss_compat/compat-initgroups.c +++ b/nis/nss_compat/compat-initgroups.c @@ -77,20 +77,6 @@ struct ent_t }; typedef struct ent_t ent_t; - -/* Positive if O_CLOEXEC is supported, negative if it is not supported, - zero if it is still undecided. This variable is shared with the - other compat functions. */ -#ifdef __ASSUME_O_CLOEXEC -# define __compat_have_cloexec 1 -#else -# ifdef O_CLOEXEC -extern int __compat_have_cloexec; -# else -# define __compat_have_cloexec -1 -# endif -#endif - /* Prototypes for local functions. */ static void blacklist_store_name (const char *, ent_t *); static int in_blacklist (const char *, int, ent_t *); @@ -141,42 +127,8 @@ internal_setgrent (ent_t *ent) if (ent->stream == NULL) status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; else - { - /* We have to make sure the file is `closed on exec'. */ - int result = 0; - - if (__compat_have_cloexec <= 0) - { - int flags; - result = flags = fcntl (fileno_unlocked (ent->stream), F_GETFD, 0); - if (result >= 0) - { -#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC - if (__compat_have_cloexec == 0) - __compat_have_cloexec = (flags & FD_CLOEXEC) ? 1 : -1; - - if (__compat_have_cloexec < 0) -#endif - { - flags |= FD_CLOEXEC; - result = fcntl (fileno_unlocked (ent->stream), F_SETFD, - flags); - } - } - } - - if (result < 0) - { - /* Something went wrong. Close the stream and return a - failure. */ - fclose (ent->stream); - ent->stream = NULL; - status = NSS_STATUS_UNAVAIL; - } - else - /* We take care of locking ourself. */ - __fsetlocking (ent->stream, FSETLOCKING_BYCALLER); - } + /* We take care of locking ourself. */ + __fsetlocking (ent->stream, FSETLOCKING_BYCALLER); return status; } diff --git a/nis/nss_compat/compat-pwd.c b/nis/nss_compat/compat-pwd.c index 28ae7fba84..0583a10b84 100644 --- a/nis/nss_compat/compat-pwd.c +++ b/nis/nss_compat/compat-pwd.c @@ -80,19 +80,6 @@ static ent_t ext_ent = { false, false, true, NSS_STATUS_SUCCESS, NULL, /* Protect global state against multiple changers. */ __libc_lock_define_initialized (static, lock) -/* Positive if O_CLOEXEC is supported, negative if it is not supported, - zero if it is still undecided. This variable is shared with the - other compat functions. */ -#ifdef __ASSUME_O_CLOEXEC -# define __compat_have_cloexec 1 -#else -# ifdef O_CLOEXEC -extern int __compat_have_cloexec; -# else -# define __compat_have_cloexec -1 -# endif -#endif - /* Prototypes for local functions. */ static void blacklist_store_name (const char *, ent_t *); static int in_blacklist (const char *, int, ent_t *); @@ -240,43 +227,8 @@ internal_setpwent (ent_t *ent, int stayopen, int needent) if (ent->stream == NULL) status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; else - { - /* We have to make sure the file is `closed on exec'. */ - int result = 0; - - if (__compat_have_cloexec <= 0) - { - int flags; - result = flags = fcntl (fileno_unlocked (ent->stream), F_GETFD, - 0); - if (result >= 0) - { -#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC - if (__compat_have_cloexec == 0) - __compat_have_cloexec = (flags & FD_CLOEXEC) ? 1 : -1; - - if (__compat_have_cloexec < 0) -#endif - { - flags |= FD_CLOEXEC; - result = fcntl (fileno_unlocked (ent->stream), F_SETFD, - flags); - } - } - } - - if (result < 0) - { - /* Something went wrong. Close the stream and return a - failure. */ - fclose (ent->stream); - ent->stream = NULL; - status = NSS_STATUS_UNAVAIL; - } - else - /* We take care of locking ourself. */ - __fsetlocking (ent->stream, FSETLOCKING_BYCALLER); - } + /* We take care of locking ourself. */ + __fsetlocking (ent->stream, FSETLOCKING_BYCALLER); } else rewind (ent->stream); diff --git a/nis/nss_compat/compat-spwd.c b/nis/nss_compat/compat-spwd.c index 550444cd80..eec3af3d15 100644 --- a/nis/nss_compat/compat-spwd.c +++ b/nis/nss_compat/compat-spwd.c @@ -77,19 +77,6 @@ static ent_t ext_ent = { false, true, false, NSS_STATUS_SUCCESS, NULL, /* Protect global state against multiple changers. */ __libc_lock_define_initialized (static, lock) -/* Positive if O_CLOEXEC is supported, negative if it is not supported, - zero if it is still undecided. This variable is shared with the - other compat functions. */ -#ifdef __ASSUME_O_CLOEXEC -# define __compat_have_cloexec 1 -#else -# ifdef O_CLOEXEC -extern int __compat_have_cloexec; -# else -# define __compat_have_cloexec -1 -# endif -#endif - /* Prototypes for local functions. */ static void blacklist_store_name (const char *, ent_t *); static int in_blacklist (const char *, int, ent_t *); @@ -196,43 +183,8 @@ internal_setspent (ent_t *ent, int stayopen, int needent) if (ent->stream == NULL) status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; else - { - /* We have to make sure the file is `closed on exec'. */ - int result = 0; - - if (__compat_have_cloexec <= 0) - { - int flags; - result = flags = fcntl (fileno_unlocked (ent->stream), F_GETFD, - 0); - if (result >= 0) - { -#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC - if (__compat_have_cloexec == 0) - __compat_have_cloexec = (flags & FD_CLOEXEC) ? 1 : -1; - - if (__compat_have_cloexec < 0) -#endif - { - flags |= FD_CLOEXEC; - result = fcntl (fileno_unlocked (ent->stream), F_SETFD, - flags); - } - } - } - - if (result < 0) - { - /* Something went wrong. Close the stream and return a - failure. */ - fclose (ent->stream); - ent->stream = NULL; - status = NSS_STATUS_UNAVAIL; - } - else - /* We take care of locking ourself. */ - __fsetlocking (ent->stream, FSETLOCKING_BYCALLER); - } + /* We take care of locking ourself. */ + __fsetlocking (ent->stream, FSETLOCKING_BYCALLER); } else rewind (ent->stream); diff --git a/nscd/connections.c b/nscd/connections.c index 205ff423de..a5ca57aea5 100644 --- a/nscd/connections.c +++ b/nscd/connections.c @@ -499,13 +499,6 @@ fail: } -#ifdef O_CLOEXEC -# define EXTRA_O_FLAGS O_CLOEXEC -#else -# define EXTRA_O_FLAGS 0 -#endif - - /* Initialize database information structures. */ void nscd_init (void) @@ -528,7 +521,7 @@ nscd_init (void) if (dbs[cnt].persistent) { /* Try to open the appropriate file on disk. */ - int fd = open (dbs[cnt].db_filename, O_RDWR | EXTRA_O_FLAGS); + int fd = open (dbs[cnt].db_filename, O_RDWR | O_CLOEXEC); if (fd != -1) { char *msg = NULL; @@ -608,7 +601,7 @@ nscd_init (void) if (dbs[cnt].shared) { dbs[cnt].ro_fd = open (dbs[cnt].db_filename, - O_RDONLY | EXTRA_O_FLAGS); + O_RDONLY | O_CLOEXEC); if (dbs[cnt].ro_fd == -1) dbg_log (_("\ cannot create read-only descriptor for \"%s\"; no mmap"), @@ -648,23 +641,23 @@ cannot create read-only descriptor for \"%s\"; no mmap"), if (dbs[cnt].persistent) { fd = open (dbs[cnt].db_filename, - O_RDWR | O_CREAT | O_EXCL | O_TRUNC | EXTRA_O_FLAGS, + O_RDWR | O_CREAT | O_EXCL | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IWUSR); if (fd != -1 && dbs[cnt].shared) ro_fd = open (dbs[cnt].db_filename, - O_RDONLY | EXTRA_O_FLAGS); + O_RDONLY | O_CLOEXEC); } else { char fname[] = _PATH_NSCD_XYZ_DB_TMP; - fd = mkostemp (fname, EXTRA_O_FLAGS); + fd = mkostemp (fname, O_CLOEXEC); /* We do not need the file name anymore after we opened another file descriptor in read-only mode. */ if (fd != -1) { if (dbs[cnt].shared) - ro_fd = open (fname, O_RDONLY | EXTRA_O_FLAGS); + ro_fd = open (fname, O_RDONLY | O_CLOEXEC); unlink (fname); } @@ -782,24 +775,6 @@ cannot create read-only descriptor for \"%s\"; no mmap"), } } -#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC - /* We do not check here whether the O_CLOEXEC provided to the - open call was successful or not. The two fcntl calls are - only performed once each per process start-up and therefore - is not noticeable at all. */ - if (paranoia - && ((dbs[cnt].wr_fd != -1 - && fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1) - || (dbs[cnt].ro_fd != -1 - && fcntl (dbs[cnt].ro_fd, F_SETFD, FD_CLOEXEC) == -1))) - { - dbg_log (_("\ -cannot set socket to close on exec: %s; disabling paranoia mode"), - strerror (errno)); - paranoia = 0; - } -#endif - if (dbs[cnt].head == NULL) { /* We do not use the persistent database. Just diff --git a/nss/Makefile b/nss/Makefile index de6c47a1db..fa0418e249 100644 --- a/nss/Makefile +++ b/nss/Makefile @@ -74,7 +74,7 @@ vpath %.c $(subdir-dirs) ../locale/programs ../intl libnss_files-routines := $(addprefix files-,$(databases)) \ - files-initgroups files-have_o_cloexec files-init + files-initgroups files-init libnss_db-dbs := $(addprefix db-,\ $(filter-out hosts network key alias,\ diff --git a/nss/nss_db/db-open.c b/nss/nss_db/db-open.c index 42ce00fe3b..1c58bd1c54 100644 --- a/nss/nss_db/db-open.c +++ b/nss/nss_db/db-open.c @@ -36,11 +36,7 @@ internal_setent (const char *file, struct nss_db_map *mapping) { enum nss_status status = NSS_STATUS_UNAVAIL; - int mode = O_RDONLY | O_LARGEFILE; -#ifdef O_CLOEXEC - mode |= O_CLOEXEC; -#endif - int fd = open_not_cancel_2 (file, mode); + int fd = open_not_cancel_2 (file, O_RDONLY | O_LARGEFILE | O_CLOEXEC); if (fd != -1) { struct nss_db_header header; diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c index dbd38a346a..265331ef21 100644 --- a/nss/nss_files/files-XXX.c +++ b/nss/nss_files/files-XXX.c @@ -78,41 +78,6 @@ internal_setent (FILE **stream) if (*stream == NULL) status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; - else - { -#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC -# ifdef O_CLOEXEC - if (__have_o_cloexec <= 0) -# endif - { - /* We have to make sure the file is `closed on exec'. */ - int result; - int flags; - - result = flags = fcntl (fileno (*stream), F_GETFD, 0); - if (result >= 0) - { -# ifdef O_CLOEXEC - if (__have_o_cloexec == 0) - __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1; - if (__have_o_cloexec < 0) -# endif - { - flags |= FD_CLOEXEC; - result = fcntl (fileno (*stream), F_SETFD, flags); - } - } - if (result < 0) - { - /* Something went wrong. Close the stream and return a - failure. */ - fclose (*stream); - *stream = NULL; - status = NSS_STATUS_UNAVAIL; - } - } -#endif - } } else rewind (*stream); diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c index de4e36499e..cf872bb603 100644 --- a/nss/nss_files/files-alias.c +++ b/nss/nss_files/files-alias.c @@ -51,41 +51,6 @@ internal_setent (FILE **stream) if (*stream == NULL) status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; - else - { -#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC -# ifdef O_CLOEXEC - if (__have_o_cloexec <= 0) -# endif - { - /* We have to make sure the file is `closed on exec'. */ - int result; - int flags; - - result = flags = fcntl (fileno (*stream), F_GETFD, 0); - if (result >= 0) - { -# ifdef O_CLOEXEC - if (__have_o_cloexec == 0) - __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1; - if (__have_o_cloexec < 0) -# endif - { - flags |= FD_CLOEXEC; - result = fcntl (fileno (*stream), F_SETFD, flags); - } - } - if (result < 0) - { - /* Something went wrong. Close the stream and return a - failure. */ - fclose (*stream); - stream = NULL; - status = NSS_STATUS_UNAVAIL; - } - } -#endif - } } else rewind (*stream); diff --git a/nss/nss_files/files-have_o_cloexec.c b/nss/nss_files/files-have_o_cloexec.c deleted file mode 100644 index 295ecccb77..0000000000 --- a/nss/nss_files/files-have_o_cloexec.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2007-2017 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 - -#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC -int __have_o_cloexec; -#endif diff --git a/posix/wordexp.c b/posix/wordexp.c index 8567c9fc50..dfc41736e6 100644 --- a/posix/wordexp.c +++ b/posix/wordexp.c @@ -833,12 +833,8 @@ exec_comm_child (char *comm, int *fildes, int showerr, int noexec) __close (fildes[1]); } else - { -#ifdef O_CLOEXEC - /* Reset the close-on-exec flag (if necessary). */ - __fcntl (fildes[1], F_SETFD, 0); -#endif - } + /* Reset the close-on-exec flag (if necessary). */ + __fcntl (fildes[1], F_SETFD, 0); /* Redirect stderr to /dev/null if we have to. */ if (showerr == 0) diff --git a/shadow/lckpwdf.c b/shadow/lckpwdf.c index 5e9a976560..09427eb233 100644 --- a/shadow/lckpwdf.c +++ b/shadow/lckpwdf.c @@ -96,39 +96,12 @@ __lckpwdf (void) /* Prevent problems caused by multiple threads. */ __libc_lock_lock (lock); - int oflags = O_WRONLY | O_CREAT; -#ifdef O_CLOEXEC - oflags |= O_CLOEXEC; -#endif + int oflags = O_WRONLY | O_CREAT | O_CLOEXEC; lock_fd = __open (PWD_LOCKFILE, oflags, 0600); if (lock_fd == -1) /* Cannot create lock file. */ RETURN_CLOSE_FD (-1); -#ifndef __ASSUME_O_CLOEXEC -# ifdef O_CLOEXEC - if (__have_o_cloexec <= 0) -# endif - { - /* Make sure file gets correctly closed when process finished. */ - int flags = __fcntl (lock_fd, F_GETFD, 0); - if (flags == -1) - /* Cannot get file flags. */ - RETURN_CLOSE_FD (-1); -# ifdef O_CLOEXEC - if (__have_o_cloexec == 0) - __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1; - if (__have_o_cloexec < 0) -# endif - { - flags |= FD_CLOEXEC; /* Close on exit. */ - if (__fcntl (lock_fd, F_SETFD, flags) < 0) - /* Cannot set new flags. */ - RETURN_CLOSE_FD (-1); - } - } -#endif - /* Now we have to get exclusive write access. Since multiple process could try this we won't stop when it first fails. Instead we set a timeout for the system call. Once the timer diff --git a/sysdeps/mach/hurd/kernel-features.h b/sysdeps/mach/hurd/kernel-features.h index 60c5bca01b..20cb3ba7bf 100644 --- a/sysdeps/mach/hurd/kernel-features.h +++ b/sysdeps/mach/hurd/kernel-features.h @@ -20,5 +20,4 @@ Almost none of these are used outside of sysdeps/unix/sysv/linux code. But those referring to POSIX-level features like O_* flags can be. */ -#define __ASSUME_O_CLOEXEC 1 #define __ASSUME_ACCEPT4 1 diff --git a/sysdeps/nacl/kernel-features.h b/sysdeps/nacl/kernel-features.h index 4a5808b56c..32834fd792 100644 --- a/sysdeps/nacl/kernel-features.h +++ b/sysdeps/nacl/kernel-features.h @@ -20,8 +20,6 @@ Almost none of these are used outside of sysdeps/unix/sysv/linux code. But those referring to POSIX-level features like O_* flags can be. */ -#define __ASSUME_O_CLOEXEC 1 - /* #define __ASSUME_ACCEPT4 1 */ diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c index 0246e91d7c..eb1706aa5c 100644 --- a/sysdeps/posix/getcwd.c +++ b/sysdeps/posix/getcwd.c @@ -281,13 +281,7 @@ __getcwd (char *buf, size_t size) while (!(thisdev == rootdev && thisino == rootino)) { if (__have_atfcts >= 0) - { - int mode = O_RDONLY; -#ifdef O_CLOEXEC - mode |= O_CLOEXEC; -#endif - fd = openat64_not_cancel_3 (fd, "..", mode); - } + fd = openat64_not_cancel_3 (fd, "..", O_RDONLY | O_CLOEXEC); else fd = -1; if (fd >= 0) diff --git a/sysdeps/posix/opendir.c b/sysdeps/posix/opendir.c index 75d833a908..909aa61884 100644 --- a/sysdeps/posix/opendir.c +++ b/sysdeps/posix/opendir.c @@ -81,6 +81,9 @@ tryopen_o_directory (void) # define EXTRA_FLAGS 0 #endif +enum { + opendir_oflags = O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE|O_CLOEXEC +}; static bool invalid_name (const char *name) @@ -110,18 +113,6 @@ need_isdir_precheck (void) return true; } - -static int -opendir_oflags (void) -{ - int flags = O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE; -#ifdef O_CLOEXEC - flags |= O_CLOEXEC; -#endif - return flags; -} - - static DIR * opendir_tail (int fd) { @@ -170,7 +161,7 @@ __opendirat (int dfd, const char *name) } } - return opendir_tail (openat_not_cancel_3 (dfd, name, opendir_oflags ())); + return opendir_tail (openat_not_cancel_3 (dfd, name, opendir_oflags)); } #endif @@ -197,39 +188,19 @@ __opendir (const char *name) } } - return opendir_tail (open_not_cancel_2 (name, opendir_oflags ())); + return opendir_tail (open_not_cancel_2 (name, opendir_oflags)); } weak_alias (__opendir, opendir) - -#ifdef __ASSUME_O_CLOEXEC -# define check_have_o_cloexec(fd) 1 -#else -static int -check_have_o_cloexec (int fd) -{ - if (__have_o_cloexec == 0) - __have_o_cloexec = (__fcntl (fd, F_GETFD, 0) & FD_CLOEXEC) == 0 ? -1 : 1; - return __have_o_cloexec > 0; -} -#endif - - DIR * internal_function __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp) { - /* We always have to set the close-on-exit flag if the user provided - the file descriptor. Otherwise only if we have no working - O_CLOEXEC support. */ -#ifdef O_CLOEXEC - if ((! close_fd && (flags & O_CLOEXEC) == 0) - || ! check_have_o_cloexec (fd)) -#endif - { - if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0) + /* We have to set the close-on-exit flag if the user provided the + file descriptor. */ + if (!close_fd + && __builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0) goto lose; - } const size_t default_allocation = (4 * BUFSIZ < sizeof (struct dirent64) ? sizeof (struct dirent64) : 4 * BUFSIZ); diff --git a/sysdeps/posix/shm_open.c b/sysdeps/posix/shm_open.c index 56a9965263..64315de8f8 100644 --- a/sysdeps/posix/shm_open.c +++ b/sysdeps/posix/shm_open.c @@ -34,10 +34,7 @@ shm_open (const char *name, int oflag, mode_t mode) { SHM_GET_NAME (EINVAL, -1, ""); - oflag |= O_NOFOLLOW; -# ifdef O_CLOEXEC - oflag |= O_CLOEXEC; -# endif + oflag |= O_NOFOLLOW | O_CLOEXEC; /* Disable asynchronous cancellation. */ int state; @@ -50,29 +47,6 @@ shm_open (const char *name, int oflag, mode_t mode) object names and the standard does not mention EISDIR. */ __set_errno (EINVAL); -# ifndef O_CLOEXEC - if (fd != -1) - { - /* We got a descriptor. Now set the FD_CLOEXEC bit. */ - int flags = fcntl (fd, F_GETFD, 0); - - if (__glibc_likely (flags != -1)) - { - flags |= FD_CLOEXEC; - flags = fcntl (fd, F_SETFD, flags); - } - - if (flags == -1) - { - /* Something went wrong. We cannot return the descriptor. */ - int save_errno = errno; - close (fd); - fd = -1; - __set_errno (save_errno); - } - } -# endif - pthread_setcancelstate (state, NULL); return fd; diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index e0eb4e2f84..fd936c5366 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -67,10 +67,6 @@ /* Support for private futexes was added in 2.6.22. */ #define __ASSUME_PRIVATE_FUTEX 1 -/* Support for various CLOEXEC and NONBLOCK flags was added in - 2.6.23. */ -#define __ASSUME_O_CLOEXEC 1 - /* Support for various CLOEXEC and NONBLOCK flags was added in 2.6.27. */ #define __ASSUME_IN_NONBLOCK 1 -- cgit v1.2.3 From 2b0b9a1c85ea93a64e55bb369e79758195512fc2 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Wed, 23 Aug 2017 10:40:14 -0300 Subject: Consolidate remaning non cancellable definitions This patch consolidate the remaning non cancellable syscall definitions on not-cancel.h header. They are: * __fcntl_nocancel: Moved from fcntl.h to not-cancel.h. * __sigsuspend_nocancel: Removed since 988f991b50 it is not used or defined anymore. * __nanosleep_nocancel: Removed since 6f33fd046b it is defined on not-cancel.h. Now all non-cancellable syscall definition are defined on not-cancel (the only exceptions is the stdio symbol __fxprintf_nocancel which uses non cancellable open and it is used on getopt implementation). Checked on x86_64-linux-gnu and with build-many-glibc.py. * include/fcntl.h (__fcntl_nocancel): Remove definition. * include/signal.h (__sigsuspend_nocancel): Likewise. * include/time.h (__nanosleep_nocancel): Likewise. * sysdeps/generic/not-cancel.h (__fcntl_nocancel): New macro. * login/utmp_file.c: Include non cancellable syscall header. * sysdeps/unix/sysv/linux/not-cancel.h (__fcntl_nocancel): New prototype. --- ChangeLog | 10 ++++++++++ include/fcntl.h | 3 --- include/signal.h | 3 --- include/time.h | 3 --- login/utmp_file.c | 1 + sysdeps/generic/not-cancel.h | 2 ++ sysdeps/unix/sysv/linux/not-cancel.h | 3 +++ 7 files changed, 16 insertions(+), 9 deletions(-) (limited to 'include/fcntl.h') diff --git a/ChangeLog b/ChangeLog index a58de05af6..59715f3161 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2017-08-23 Adhemerval Zanella + + * include/fcntl.h (__fcntl_nocancel): Remove definition. + * include/signal.h (__sigsuspend_nocancel): Likewise. + * include/time.h (__nanosleep_nocancel): Likewise. + * sysdeps/generic/not-cancel.h (__fcntl_nocancel): New macro. + * login/utmp_file.c: Include non cancellable syscall header. + * sysdeps/unix/sysv/linux/not-cancel.h (__fcntl_nocancel): New + prototype. + 2017-08-23 H.J. Lu * sysdeps/x86_64/fpu/svml_d_sincos8_core.S: Replace AVX512F diff --git a/include/fcntl.h b/include/fcntl.h index 9a007c358c..3d68c5ec67 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -9,10 +9,7 @@ extern int __libc_open64 (const char *file, int oflag, ...); extern int __libc_open (const char *file, int oflag, ...); libc_hidden_proto (__libc_open) extern int __libc_fcntl (int fd, int cmd, ...) attribute_hidden; -#ifndef NO_CANCELLATION -extern int __fcntl_nocancel (int fd, int cmd, ...) attribute_hidden; libc_hidden_proto (__libc_fcntl) -#endif extern int __open (const char *__file, int __oflag, ...); libc_hidden_proto (__open) extern int __fcntl (int __fd, int __cmd, ...); diff --git a/include/signal.h b/include/signal.h index bcf1455ae7..61ad422dcb 100644 --- a/include/signal.h +++ b/include/signal.h @@ -26,9 +26,6 @@ extern int __sigprocmask (int __how, const sigset_t *__set, sigset_t *__oset); extern int __sigsuspend (const sigset_t *__set); libc_hidden_proto (__sigsuspend) -#ifndef NO_CANCELLATION -extern int __sigsuspend_nocancel (const sigset_t *__set) attribute_hidden; -#endif extern int __sigwait (const sigset_t *__set, int *__sig); libc_hidden_proto (__sigwait) extern int __sigwaitinfo (const sigset_t *__set, siginfo_t *__info); diff --git a/include/time.h b/include/time.h index 9956b82eb8..73696082cc 100644 --- a/include/time.h +++ b/include/time.h @@ -79,9 +79,6 @@ extern struct tm *__tz_convert (const time_t *timer, int use_localtime, struct t extern int __nanosleep (const struct timespec *__requested_time, struct timespec *__remaining); hidden_proto (__nanosleep) -extern int __nanosleep_nocancel (const struct timespec *__requested_time, - struct timespec *__remaining) - attribute_hidden; extern int __getdate_r (const char *__string, struct tm *__resbufp); diff --git a/login/utmp_file.c b/login/utmp_file.c index d410b6c533..e0d27100ab 100644 --- a/login/utmp_file.c +++ b/login/utmp_file.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "utmp-private.h" #include "utmp-equal.h" diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h index 70ead5510a..e5a850c6fd 100644 --- a/sysdeps/generic/not-cancel.h +++ b/sysdeps/generic/not-cancel.h @@ -42,5 +42,7 @@ __pause () #define __nanosleep_nocancel(requested_time, remaining) \ __nanosleep (requested_time, remaining) +#define __fcntl_nocancel(fd, cmd, ...) \ + __fcntl (fd, cmd, __VA_ARGS__) #define NO_CANCELLATION 1 diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h index f73b2bbe8c..ae0b059e75 100644 --- a/sysdeps/unix/sysv/linux/not-cancel.h +++ b/sysdeps/unix/sysv/linux/not-cancel.h @@ -85,4 +85,7 @@ libc_hidden_proto (__pause_nocancel) __typeof (__nanosleep) __nanosleep_nocancel; hidden_proto (__nanosleep_nocancel) +/* Uncancelable fcntl. */ +__typeof (__fcntl) __fcntl_nocancel attribute_hidden; + #endif /* NOT_CANCEL_H */ -- cgit v1.2.3 From 329ea513b451ae8322aa7a24ed84da13992af2dd Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Tue, 3 Apr 2018 18:26:44 -0400 Subject: Avoid cancellable I/O primitives in ld.so. Neither the entry points, nor lazy symbol resolution, nor initial shared library load-up, are cancellation points, so ld.so should exclusively use I/O primitives that are not cancellable. We currently achieve this by having the cancellation hooks compile as no-ops when IS_IN(rtld); this patch changes to using exclusively _nocancel primitives in the source code instead, which makes the intent clearer and significantly reduces the amount of code compiled under IS_IN(rtld) as well as IS_IN(libc) -- in particular, elf/Makefile no longer thinks we require a copy of unwind.c in rtld-libc.a. (The older mechanism is preserved as a backstop.) The bulk of the change is splitting up the files that define the _nocancel I/O functions, so they don't also define the variants that *are* cancellation points; after which, the existing logic for picking out the bits of libc that need to be recompiled as part of ld.so Just Works. I did this for all of the _nocancel functions, not just the ones used by ld.so, for consistency. fcntl was a little tricky because it's only a cancellation point for certain opcodes (F_SETLKW(64), which can block), and the existing __fcntl_nocancel wasn't applying the FCNTL_ADJUST_CMD hook, which strikes me as asking for trouble, especially as the only nontrivial definition of FCNTL_ADJUST_CMD (for powerpc64) changes F_*LK* opcodes. To fix this, fcntl_common moves to fcntl_nocancel.c along with __fcntl_nocancel, and changes its name to the extern (but hidden) symbol __fcntl_nocancel_adjusted, so that regular fcntl can continue calling it. __fcntl_nocancel now applies FCNTL_ADJUST_CMD; so that both both fcntl.c and fcntl_nocancel.c can see it, the only nontrivial definition moves from sysdeps/u/s/l/powerpc/powerpc64/fcntl.c to .../powerpc64/sysdep.h and becomes entirely a macro, instead of a macro that calls an inline function. The nptl version of libpthread also changes a little, because its "compat-routines" formerly included files that defined all the _nocancel functions it uses; instead of continuing to duplicate them, I exported the relevant ones from libc.so as GLIBC_PRIVATE. Since the Linux fcntl.c calls a function defined by fcntl_nocancel.c, it can no longer be used from libpthread.so; instead, introduce a custom forwarder, pt-fcntl.c, and export __libc_fcntl from libc.so as GLIBC_PRIVATE. The nios2-linux ABI doesn't include a copy of vfork() in libpthread, and it was handling that by manipulating libpthread-routines in .../linux/nios2/Makefile; it is cleaner to do what other such ports do, and have a pt-vfork.S that defines no symbols. Right now, it appears that Hurd does not implement _nocancel I/O, so sysdeps/generic/not-cancel.h will forward everything back to the regular functions. This changed the names of some of the functions that sysdeps/mach/hurd/dl-sysdep.c needs to interpose. * elf/dl-load.c, elf/dl-misc.c, elf/dl-profile.c, elf/rtld.c * sysdeps/unix/sysv/linux/dl-sysdep.c Include not-cancel.h. Use __close_nocancel instead of __close, __open64_nocancel instead of __open, __read_nocancel instead of __libc_read, and __write_nocancel instead of __libc_write. * csu/check_fds.c (check_one_fd) * sysdeps/posix/fdopendir.c (__fdopendir) * sysdeps/posix/opendir.c (__alloc_dir): Use __fcntl_nocancel instead of __fcntl and/or __libc_fcntl. * sysdeps/unix/sysv/linux/pthread_setname.c (pthread_setname_np) * sysdeps/unix/sysv/linux/pthread_getname.c (pthread_getname_np) * sysdeps/unix/sysv/linux/i386/smp.h (is_smp_system): Use __open64_nocancel instead of __open_nocancel. * sysdeps/unix/sysv/linux/not-cancel.h: Move all of the hidden_proto declarations to the end and issue them if either IS_IN(libc) or IS_IN(rtld). * sysdeps/unix/sysv/linux/Makefile [subdir=io] (sysdep_routines): Add close_nocancel, fcntl_nocancel, nanosleep_nocancel, open_nocancel, open64_nocancel, openat_nocancel, pause_nocancel, read_nocancel, waitpid_nocancel, write_nocancel. * io/Versions [GLIBC_PRIVATE]: Add __libc_fcntl, __fcntl_nocancel, __open64_nocancel, __write_nocancel. * posix/Versions: Add __nanosleep_nocancel, __pause_nocancel. * nptl/pt-fcntl.c: New file. * nptl/Makefile (pthread-compat-wrappers): Remove fcntl. (libpthread-routines): Add pt-fcntl. * include/fcntl.h (__fcntl_nocancel_adjusted): New function. (__libc_fcntl): Remove attribute_hidden. * sysdeps/unix/sysv/linux/fcntl.c (__libc_fcntl): Call __fcntl_nocancel_adjusted, not fcntl_common. (__fcntl_nocancel): Move to new file fcntl_nocancel.c. (fcntl_common): Rename to __fcntl_nocancel_adjusted; also move to fcntl_nocancel.c. * sysdeps/unix/sysv/linux/fcntl_nocancel.c: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c: Remove file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: Define FCNTL_ADJUST_CMD here, as a self-contained macro. * sysdeps/unix/sysv/linux/close.c: Move __close_nocancel to... * sysdeps/unix/sysv/linux/close_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/nanosleep.c: Move __nanosleep_nocancel to... * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/open.c: Move __open_nocancel to... * sysdeps/unix/sysv/linux/open_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/open64.c: Move __open64_nocancel to... * sysdeps/unix/sysv/linux/open64_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/openat.c: Move __openat_nocancel to... * sysdeps/unix/sysv/linux/openat_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/openat64.c: Move __openat64_nocancel to... * sysdeps/unix/sysv/linux/openat64_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/pause.c: Move __pause_nocancel to... * sysdeps/unix/sysv/linux/pause_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/read.c: Move __read_nocancel to... * sysdeps/unix/sysv/linux/read_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/waitpid.c: Move __waitpid_nocancel to... * sysdeps/unix/sysv/linux/waitpid_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/write.c: Move __write_nocancel to... * sysdeps/unix/sysv/linux/write_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/nios2/Makefile: Don't override libpthread-routines. * sysdeps/unix/sysv/linux/nios2/pt-vfork.S: New file which defines nothing. * sysdeps/mach/hurd/dl-sysdep.c: Define __read instead of __libc_read, and __write instead of __libc_write. Define __open64 in addition to __open. --- ChangeLog | 75 ++++++++++++++++++++++ csu/check_fds.c | 3 +- elf/dl-load.c | 35 +++++----- elf/dl-misc.c | 6 +- elf/dl-profile.c | 14 ++-- elf/rtld.c | 3 +- include/fcntl.h | 3 +- io/Versions | 6 ++ nptl/Makefile | 4 +- posix/Versions | 1 + sysdeps/mach/hurd/dl-sysdep.c | 14 ++-- sysdeps/posix/fdopendir.c | 2 +- sysdeps/posix/opendir.c | 2 +- sysdeps/unix/pt-fcntl.c | 49 ++++++++++++++ sysdeps/unix/sysv/linux/Makefile | 7 +- sysdeps/unix/sysv/linux/close.c | 11 ---- sysdeps/unix/sysv/linux/close_nocancel.c | 28 ++++++++ sysdeps/unix/sysv/linux/dl-sysdep.c | 7 +- sysdeps/unix/sysv/linux/fcntl.c | 41 +----------- sysdeps/unix/sysv/linux/fcntl_nocancel.c | 65 +++++++++++++++++++ sysdeps/unix/sysv/linux/i386/smp.h | 2 +- sysdeps/unix/sysv/linux/nanosleep.c | 10 +-- sysdeps/unix/sysv/linux/nanosleep_nocancel.c | 29 +++++++++ sysdeps/unix/sysv/linux/nios2/Makefile | 4 -- sysdeps/unix/sysv/linux/nios2/pt-vfork.S | 1 + sysdeps/unix/sysv/linux/not-cancel.h | 25 ++++---- sysdeps/unix/sysv/linux/open.c | 25 +------- sysdeps/unix/sysv/linux/open64.c | 30 +-------- sysdeps/unix/sysv/linux/open64_nocancel.c | 54 ++++++++++++++++ sysdeps/unix/sysv/linux/open_nocancel.c | 46 +++++++++++++ sysdeps/unix/sysv/linux/openat.c | 24 +------ sysdeps/unix/sysv/linux/openat64.c | 27 +------- sysdeps/unix/sysv/linux/openat64_nocancel.c | 51 +++++++++++++++ sysdeps/unix/sysv/linux/openat_nocancel.c | 43 +++++++++++++ sysdeps/unix/sysv/linux/pause.c | 12 ---- sysdeps/unix/sysv/linux/pause_nocancel.c | 33 ++++++++++ sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c | 32 --------- sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h | 9 +++ sysdeps/unix/sysv/linux/pthread_getname.c | 2 +- sysdeps/unix/sysv/linux/pthread_setname.c | 2 +- sysdeps/unix/sysv/linux/read.c | 12 ---- sysdeps/unix/sysv/linux/read_nocancel.c | 28 ++++++++ sysdeps/unix/sysv/linux/waitpid.c | 15 +---- sysdeps/unix/sysv/linux/waitpid_nocancel.c | 34 ++++++++++ sysdeps/unix/sysv/linux/write.c | 12 ---- sysdeps/unix/sysv/linux/write_nocancel.c | 28 ++++++++ 46 files changed, 667 insertions(+), 299 deletions(-) create mode 100644 sysdeps/unix/pt-fcntl.c create mode 100644 sysdeps/unix/sysv/linux/close_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/fcntl_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/nanosleep_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/nios2/pt-vfork.S create mode 100644 sysdeps/unix/sysv/linux/open64_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/open_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/openat64_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/openat_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/pause_nocancel.c delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c create mode 100644 sysdeps/unix/sysv/linux/read_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/waitpid_nocancel.c create mode 100644 sysdeps/unix/sysv/linux/write_nocancel.c (limited to 'include/fcntl.h') diff --git a/ChangeLog b/ChangeLog index c1ff22b191..3dc59d4067 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,78 @@ +2018-06-12 Zack Weinberg + + * elf/dl-load.c, elf/dl-misc.c, elf/dl-profile.c, elf/rtld.c + * sysdeps/unix/sysv/linux/dl-sysdep.c + Include not-cancel.h. Use __close_nocancel instead of __close, + __open64_nocancel instead of __open, __read_nocancel instead of + __libc_read, and __write_nocancel instead of __libc_write. + + * csu/check_fds.c (check_one_fd) + * sysdeps/posix/fdopendir.c (__fdopendir) + * sysdeps/posix/opendir.c (__alloc_dir): Use __fcntl_nocancel + instead of __fcntl and/or __libc_fcntl. + + * sysdeps/unix/sysv/linux/pthread_setname.c (pthread_setname_np) + * sysdeps/unix/sysv/linux/pthread_getname.c (pthread_getname_np) + * sysdeps/unix/sysv/linux/i386/smp.h (is_smp_system): + Use __open64_nocancel instead of __open_nocancel. + + * sysdeps/unix/sysv/linux/not-cancel.h: Move all of the + hidden_proto declarations to the end and issue them if either + IS_IN(libc) or IS_IN(rtld). + * sysdeps/unix/sysv/linux/Makefile [subdir=io] (sysdep_routines): + Add close_nocancel, fcntl_nocancel, nanosleep_nocancel, + open_nocancel, open64_nocancel, openat_nocancel, pause_nocancel, + read_nocancel, waitpid_nocancel, write_nocancel. + + * io/Versions [GLIBC_PRIVATE]: Add __libc_fcntl, + __fcntl_nocancel, __open64_nocancel, __write_nocancel. + * posix/Versions: Add __nanosleep_nocancel, __pause_nocancel. + + * nptl/pt-fcntl.c: New file. + * nptl/Makefile (pthread-compat-wrappers): Remove fcntl. + (libpthread-routines): Add pt-fcntl. + * include/fcntl.h (__fcntl_nocancel_adjusted): New function. + (__libc_fcntl): Remove attribute_hidden. + * sysdeps/unix/sysv/linux/fcntl.c (__libc_fcntl): Call + __fcntl_nocancel_adjusted, not fcntl_common. + (__fcntl_nocancel): Move to new file fcntl_nocancel.c. + (fcntl_common): Rename to __fcntl_nocancel_adjusted; also move + to fcntl_nocancel.c. + * sysdeps/unix/sysv/linux/fcntl_nocancel.c: New file. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c: Remove file. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: + Define FCNTL_ADJUST_CMD here, as a self-contained macro. + + * sysdeps/unix/sysv/linux/close.c: Move __close_nocancel to... + * sysdeps/unix/sysv/linux/close_nocancel.c: ...this new file. + * sysdeps/unix/sysv/linux/nanosleep.c: Move __nanosleep_nocancel to... + * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: ...this new file. + * sysdeps/unix/sysv/linux/open.c: Move __open_nocancel to... + * sysdeps/unix/sysv/linux/open_nocancel.c: ...this new file. + * sysdeps/unix/sysv/linux/open64.c: Move __open64_nocancel to... + * sysdeps/unix/sysv/linux/open64_nocancel.c: ...this new file. + * sysdeps/unix/sysv/linux/openat.c: Move __openat_nocancel to... + * sysdeps/unix/sysv/linux/openat_nocancel.c: ...this new file. + * sysdeps/unix/sysv/linux/openat64.c: Move __openat64_nocancel to... + * sysdeps/unix/sysv/linux/openat64_nocancel.c: ...this new file. + * sysdeps/unix/sysv/linux/pause.c: Move __pause_nocancel to... + * sysdeps/unix/sysv/linux/pause_nocancel.c: ...this new file. + * sysdeps/unix/sysv/linux/read.c: Move __read_nocancel to... + * sysdeps/unix/sysv/linux/read_nocancel.c: ...this new file. + * sysdeps/unix/sysv/linux/waitpid.c: Move __waitpid_nocancel to... + * sysdeps/unix/sysv/linux/waitpid_nocancel.c: ...this new file. + * sysdeps/unix/sysv/linux/write.c: Move __write_nocancel to... + * sysdeps/unix/sysv/linux/write_nocancel.c: ...this new file. + + * sysdeps/unix/sysv/linux/nios2/Makefile: Don't override + libpthread-routines. + * sysdeps/unix/sysv/linux/nios2/pt-vfork.S: New file which + defines nothing. + + * sysdeps/mach/hurd/dl-sysdep.c: Define __read instead of + __libc_read, and __write instead of __libc_write. Define + __open64 in addition to __open. + 2018-06-12 H.J. Lu [BZ #23250] diff --git a/csu/check_fds.c b/csu/check_fds.c index 2b181d44ab..605ee4f3f4 100644 --- a/csu/check_fds.c +++ b/csu/check_fds.c @@ -39,8 +39,7 @@ static void check_one_fd (int fd, int mode) { - /* Note that fcntl() with this parameter is not a cancellation point. */ - if (__builtin_expect (__libc_fcntl (fd, F_GETFD), 0) == -1 + if (__builtin_expect (__fcntl_nocancel (fd, F_GETFD), 0) == -1 && errno == EBADF) { const char *name; diff --git a/elf/dl-load.c b/elf/dl-load.c index 431236920f..c52d011efd 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -44,7 +44,7 @@ #include #include #include - +#include #include #if BYTE_ORDER == BIG_ENDIAN @@ -776,7 +776,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l, { /* The file might already be closed. */ if (fd != -1) - (void) __close (fd); + (void) __close_nocancel (fd); if (l != NULL && l->l_origin != (char *) -1l) free ((char *) l->l_origin); free (l); @@ -835,7 +835,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, { /* The object is already loaded. Just bump its reference count and return it. */ - __close (fd); + __close_nocancel (fd); /* If the name is not in the list of names for this object add it. */ @@ -863,7 +863,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, /* No need to bump the refcount of the real object, ld.so will never be unloaded. */ - __close (fd); + __close_nocancel (fd); /* Add the map for the mirrored object to the object list. */ _dl_add_to_namespace_list (l, nsid); @@ -877,7 +877,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, /* We are not supposed to load the object unless it is already loaded. So return now. */ free (realname); - __close (fd); + __close_nocancel (fd); return NULL; } @@ -896,7 +896,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, if (_dl_zerofd == -1) { free (realname); - __close (fd); + __close_nocancel (fd); _dl_signal_error (errno, NULL, NULL, N_("cannot open zero fill device")); } @@ -962,7 +962,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, { phdr = alloca (maplength); __lseek (fd, header->e_phoff, SEEK_SET); - if ((size_t) __libc_read (fd, (void *) phdr, maplength) != maplength) + if ((size_t) __read_nocancel (fd, (void *) phdr, maplength) != maplength) { errstring = N_("cannot read file data"); goto call_lose_errno; @@ -1232,7 +1232,7 @@ cannot enable executable stack as shared object requires"); l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr; /* We are done mapping in the file. We no longer need the descriptor. */ - if (__glibc_unlikely (__close (fd) != 0)) + if (__glibc_unlikely (__close_nocancel (fd) != 0)) { errstring = N_("cannot close file descriptor"); goto call_lose_errno; @@ -1447,7 +1447,7 @@ open_verify (const char *name, int fd, { /* An audit library changed what we're supposed to open, so FD no longer matches it. */ - __close (fd); + __close_nocancel (fd); fd = -1; } } @@ -1455,7 +1455,7 @@ open_verify (const char *name, int fd, if (fd == -1) /* Open the file. We always open files read-only. */ - fd = __open (name, O_RDONLY | O_CLOEXEC); + fd = __open64_nocancel (name, O_RDONLY | O_CLOEXEC); if (fd != -1) { @@ -1474,8 +1474,8 @@ open_verify (const char *name, int fd, /* Read in the header. */ do { - ssize_t retlen = __libc_read (fd, fbp->buf + fbp->len, - sizeof (fbp->buf) - fbp->len); + ssize_t retlen = __read_nocancel (fd, fbp->buf + fbp->len, + sizeof (fbp->buf) - fbp->len); if (retlen <= 0) break; fbp->len += retlen; @@ -1598,7 +1598,8 @@ open_verify (const char *name, int fd, { phdr = alloca (maplength); __lseek (fd, ehdr->e_phoff, SEEK_SET); - if ((size_t) __libc_read (fd, (void *) phdr, maplength) != maplength) + if ((size_t) __read_nocancel (fd, (void *) phdr, maplength) + != maplength) { read_error: errval = errno; @@ -1648,7 +1649,7 @@ open_verify (const char *name, int fd, abi_note = abi_note_malloced; } __lseek (fd, ph->p_offset, SEEK_SET); - if (__libc_read (fd, (void *) abi_note, size) != size) + if (__read_nocancel (fd, (void *) abi_note, size) != size) { free (abi_note_malloced); goto read_error; @@ -1680,7 +1681,7 @@ open_verify (const char *name, int fd, || (GLRO(dl_osversion) && GLRO(dl_osversion) < osversion)) { close_and_out: - __close (fd); + __close_nocancel (fd); __set_errno (ENOENT); fd = -1; } @@ -1797,7 +1798,7 @@ open_path (const char *name, size_t namelen, int mode, /* The shared object cannot be tested for being SUID or this bit is not set. In this case we must not use this object. */ - __close (fd); + __close_nocancel (fd); fd = -1; /* We simply ignore the file, signal this by setting the error value which would have been set by `open'. */ @@ -1818,7 +1819,7 @@ open_path (const char *name, size_t namelen, int mode, { /* No memory for the name, we certainly won't be able to load and link it. */ - __close (fd); + __close_nocancel (fd); return -1; } } diff --git a/elf/dl-misc.c b/elf/dl-misc.c index b7174994cd..2eb81eeb02 100644 --- a/elf/dl-misc.c +++ b/elf/dl-misc.c @@ -33,7 +33,7 @@ #include #include <_itoa.h> #include - +#include /* Read the whole contents of FILE into new mmap'd space with given protections. *SIZEP gets the size of the file. On error MAP_FAILED @@ -44,7 +44,7 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) { void *result = MAP_FAILED; struct stat64 st; - int fd = __open (file, O_RDONLY | O_CLOEXEC); + int fd = __open64_nocancel (file, O_RDONLY | O_CLOEXEC); if (fd >= 0) { if (__fxstat64 (_STAT_VER, fd, &st) >= 0) @@ -65,7 +65,7 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) #endif , fd, 0); } - __close (fd); + __close_nocancel (fd); } return result; } diff --git a/elf/dl-profile.c b/elf/dl-profile.c index 7f15352123..bac3718c11 100644 --- a/elf/dl-profile.c +++ b/elf/dl-profile.c @@ -35,6 +35,7 @@ #include #include #include +#include /* The LD_PROFILE feature has to be implemented different to the normal profiling using the gmon/ functions. The problem is that an @@ -324,7 +325,7 @@ _dl_start_profile (void) *cp++ = '/'; __stpcpy (__stpcpy (cp, GLRO(dl_profile)), ".profile"); - fd = __open (filename, O_RDWR | O_CREAT | O_NOFOLLOW, DEFFILEMODE); + fd = __open64_nocancel (filename, O_RDWR|O_CREAT|O_NOFOLLOW, DEFFILEMODE); if (fd == -1) { char buf[400]; @@ -335,7 +336,7 @@ _dl_start_profile (void) print_error: errnum = errno; if (fd != -1) - __close (fd); + __close_nocancel (fd); _dl_error_printf (errstr, filename, __strerror_r (errnum, buf, sizeof buf)); return; @@ -364,15 +365,14 @@ _dl_start_profile (void) goto print_error; } - if (TEMP_FAILURE_RETRY (__libc_write (fd, buf, (expected_size - & (GLRO(dl_pagesize) - - 1)))) + if (TEMP_FAILURE_RETRY + (__write_nocancel (fd, buf, (expected_size & (GLRO(dl_pagesize) - 1)))) < 0) goto cannot_create; } else if (st.st_size != expected_size) { - __close (fd); + __close_nocancel (fd); wrong_format: if (addr != NULL) @@ -392,7 +392,7 @@ _dl_start_profile (void) } /* We don't need the file descriptor anymore. */ - __close (fd); + __close_nocancel (fd); /* Pointer to data after the header. */ hist = (char *) (addr + 1); diff --git a/elf/rtld.c b/elf/rtld.c index e7681ebb1f..8c732adb68 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -2673,7 +2674,7 @@ process_envvars (enum mode *modep) *--startp = '.'; startp = memcpy (startp - name_len, debug_output, name_len); - GLRO(dl_debug_fd) = __open (startp, flags, DEFFILEMODE); + GLRO(dl_debug_fd) = __open64_nocancel (startp, flags, DEFFILEMODE); if (GLRO(dl_debug_fd) == -1) /* We use standard output if opening the file failed. */ GLRO(dl_debug_fd) = STDOUT_FILENO; diff --git a/include/fcntl.h b/include/fcntl.h index 3d68c5ec67..966f797890 100644 --- a/include/fcntl.h +++ b/include/fcntl.h @@ -8,8 +8,9 @@ libc_hidden_proto (__open64) extern int __libc_open64 (const char *file, int oflag, ...); extern int __libc_open (const char *file, int oflag, ...); libc_hidden_proto (__libc_open) -extern int __libc_fcntl (int fd, int cmd, ...) attribute_hidden; +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 __open (const char *__file, int __oflag, ...); libc_hidden_proto (__open) extern int __fcntl (int __fd, int __cmd, ...); diff --git a/io/Versions b/io/Versions index 98898cb9d5..4448b7197c 100644 --- a/io/Versions +++ b/io/Versions @@ -128,4 +128,10 @@ libc { GLIBC_2.27 { copy_file_range; } + GLIBC_PRIVATE { + __libc_fcntl; + __fcntl_nocancel; + __open64_nocancel; + __write_nocancel; + } } diff --git a/nptl/Makefile b/nptl/Makefile index 94be92c789..6cfc8c60ee 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -36,7 +36,7 @@ static-only-routines = pthread_atfork # We need to provide certain routines for compatibility with existing # binaries. pthread-compat-wrappers = \ - write read close fcntl accept \ + write read close accept \ connect recv recvfrom send \ sendto fsync lseek lseek64 \ msync nanosleep open open64 pause \ @@ -120,7 +120,7 @@ libpthread-routines = nptl-init vars events version pt-interp \ cancellation \ lowlevellock \ lll_timedlock_wait lll_timedwait_tid \ - pt-fork pt-vfork \ + pt-fork pt-vfork pt-fcntl \ $(pthread-compat-wrappers) \ pt-raise pt-system \ flockfile ftrylockfile funlockfile \ diff --git a/posix/Versions b/posix/Versions index 65e96870e1..cad4c23e8c 100644 --- a/posix/Versions +++ b/posix/Versions @@ -139,5 +139,6 @@ libc { } GLIBC_PRIVATE { __libc_fork; __libc_pread; __libc_pwrite; + __nanosleep_nocancel; __pause_nocancel; } } diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index 547108805e..ec55c47f35 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -339,6 +339,7 @@ open_file (const char *file_name, int flags, } check_no_hidden(__open); +check_no_hidden (__open64); int weak_function __open (const char *file_name, int mode, ...) { @@ -349,6 +350,7 @@ __open (const char *file_name, int mode, ...) else return (int)port; } +weak_alias (__open, __open64) check_no_hidden(__close); int weak_function @@ -359,9 +361,9 @@ __close (int fd) return 0; } -check_no_hidden(__libc_read); +check_no_hidden(__read); __ssize_t weak_function -__libc_read (int fd, void *buf, size_t nbytes) +__read (int fd, void *buf, size_t nbytes) { error_t err; char *data; @@ -381,11 +383,11 @@ __libc_read (int fd, void *buf, size_t nbytes) return nread; } -libc_hidden_weak (__libc_read) +libc_hidden_weak (__read) -check_no_hidden(__libc_write); +check_no_hidden(__write); __ssize_t weak_function -__libc_write (int fd, const void *buf, size_t nbytes) +__write (int fd, const void *buf, size_t nbytes) { error_t err; mach_msg_type_number_t nwrote; @@ -398,7 +400,7 @@ __libc_write (int fd, const void *buf, size_t nbytes) return nwrote; } -libc_hidden_weak (__libc_write) +libc_hidden_weak (__write) /* This is only used for printing messages (see dl-misc.c). */ check_no_hidden(__writev); diff --git a/sysdeps/posix/fdopendir.c b/sysdeps/posix/fdopendir.c index ab4541f7fc..dafb5d20c1 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 (fd, F_GETFL); + int flags = __fcntl_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 dea23b2ff5..0875385f65 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 - && __builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0) + && __glibc_unlikely (__fcntl_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 new file mode 100644 index 0000000000..8113d52b86 --- /dev/null +++ b/sysdeps/unix/pt-fcntl.c @@ -0,0 +1,49 @@ +/* ABI compatibility for 'fcntl' symbol in libpthread ABI. + 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 +#include + +/* libpthread once had its own fcntl, though there was no apparent reason + for it. There is no use in having a separate symbol in libpthread, but + the historical ABI requires it. For static linking, there is no need to + provide anything here--the libc version will be linked in. For shared + library ABI compatibility, there must be __fcntl and fcntl symbols in + libpthread.so. */ + +#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_28) + +static int +fcntl_compat (int fd, int cmd, ...) +{ + void *arg; + va_list ap; + va_start (ap, cmd); + arg = va_arg (ap, void *); + va_end (ap); + return __libc_fcntl (fd, cmd, arg); +} + +weak_alias (fcntl_compat, fcntl_alias) +compat_symbol (libpthread, fcntl_alias, fcntl, GLIBC_2_0); + +weak_alias (fcntl_compat, __fcntl_alias) +compat_symbol (libpthread, __fcntl_alias, __fcntl, GLIBC_2_0); + +#endif diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index cd6244f7ea..215fd5d136 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -167,7 +167,12 @@ endif ifeq ($(subdir),io) sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \ - sync_file_range fallocate fallocate64 + sync_file_range fallocate fallocate64 \ + close_nocancel fcntl_nocancel nanosleep_nocancel \ + open_nocancel open64_nocancel \ + openat_nocancel openat64_nocancel \ + pause_nocancel read_nocancel waitpid_nocancel write_nocancel + sysdep_headers += bits/fcntl-linux.h tests += tst-fallocate tst-fallocate64 diff --git a/sysdeps/unix/sysv/linux/close.c b/sysdeps/unix/sysv/linux/close.c index c832d27a0f..fa0938bd89 100644 --- a/sysdeps/unix/sysv/linux/close.c +++ b/sysdeps/unix/sysv/linux/close.c @@ -29,14 +29,3 @@ __close (int fd) libc_hidden_def (__close) strong_alias (__close, __libc_close) weak_alias (__close, close) - -# if !IS_IN (rtld) -int -__close_nocancel (int fd) -{ - return INLINE_SYSCALL_CALL (close, fd); -} -#else -strong_alias (__libc_close, __close_nocancel) -#endif -libc_hidden_def (__close_nocancel) diff --git a/sysdeps/unix/sysv/linux/close_nocancel.c b/sysdeps/unix/sysv/linux/close_nocancel.c new file mode 100644 index 0000000000..7d744f9096 --- /dev/null +++ b/sysdeps/unix/sysv/linux/close_nocancel.c @@ -0,0 +1,28 @@ +/* Linux close syscall implementation -- non-cancellable. + 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 +#include + +int +__close_nocancel (int fd) +{ + return INLINE_SYSCALL_CALL (close, fd); +} +libc_hidden_def (__close_nocancel) diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c index b4cda3486a..0477e0e5fa 100644 --- a/sysdeps/unix/sysv/linux/dl-sysdep.c +++ b/sysdeps/unix/sysv/linux/dl-sysdep.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef SHARED # define DL_SYSDEP_INIT frob_brk () @@ -87,11 +88,11 @@ _dl_discover_osversion (void) if (__uname (&uts)) { /* This was not successful. Now try reading the /proc filesystem. */ - int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY); + int fd = __open64_nocancel ("/proc/sys/kernel/osrelease", O_RDONLY); if (fd < 0) return -1; - ssize_t reslen = __read (fd, bufmem, sizeof (bufmem)); - __close (fd); + ssize_t reslen = __read_nocancel (fd, bufmem, sizeof (bufmem)); + __close_nocancel (fd); if (reslen <= 0) /* This also didn't work. We give up since we cannot make sure the library can actually work. */ diff --git a/sysdeps/unix/sysv/linux/fcntl.c b/sysdeps/unix/sysv/linux/fcntl.c index a3cb2aea10..e3992dc9d4 100644 --- a/sysdeps/unix/sysv/linux/fcntl.c +++ b/sysdeps/unix/sysv/linux/fcntl.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2000-2018 Free Software Foundation, Inc. +/* Linux fcntl syscall implementation. + Copyright (C) 2000-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 @@ -29,24 +30,6 @@ # define FCNTL_ADJUST_CMD(__cmd) __cmd #endif -static int -fcntl_common (int fd, int cmd, void *arg) -{ - if (cmd == F_GETOWN) - { - INTERNAL_SYSCALL_DECL (err); - struct f_owner_ex fex; - int res = INTERNAL_SYSCALL_CALL (fcntl64, err, fd, F_GETOWN_EX, &fex); - if (!INTERNAL_SYSCALL_ERROR_P (res, err)) - return fex.type == F_OWNER_GID ? -fex.pid : fex.pid; - - return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (res, - err)); - } - - return INLINE_SYSCALL_CALL (fcntl64, fd, cmd, (void *) arg); -} - int __libc_fcntl (int fd, int cmd, ...) { @@ -62,28 +45,10 @@ __libc_fcntl (int fd, int cmd, ...) if (cmd == F_SETLKW || cmd == F_SETLKW64) return SYSCALL_CANCEL (fcntl64, fd, cmd, (void *) arg); - return fcntl_common (fd, cmd, arg); + return __fcntl_nocancel_adjusted (fd, cmd, arg); } libc_hidden_def (__libc_fcntl) -#if !IS_IN (rtld) -int -__fcntl_nocancel (int fd, int cmd, ...) -{ - va_list ap; - void *arg; - - va_start (ap, cmd); - arg = va_arg (ap, void *); - va_end (ap); - - return fcntl_common (fd, cmd, arg); -} -#else -strong_alias (__libc_fcntl, __fcntl_nocancel) -#endif -libc_hidden_def (__fcntl_nocancel) - weak_alias (__libc_fcntl, __fcntl) libc_hidden_weak (__fcntl) weak_alias (__libc_fcntl, fcntl) diff --git a/sysdeps/unix/sysv/linux/fcntl_nocancel.c b/sysdeps/unix/sysv/linux/fcntl_nocancel.c new file mode 100644 index 0000000000..f50e382c4a --- /dev/null +++ b/sysdeps/unix/sysv/linux/fcntl_nocancel.c @@ -0,0 +1,65 @@ +/* Linux fcntl syscall implementation -- non-cancellable. + 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 +#include +#include +#include + +#ifndef __NR_fcntl64 +# define __NR_fcntl64 __NR_fcntl +#endif + +#ifndef FCNTL_ADJUST_CMD +# define FCNTL_ADJUST_CMD(__cmd) __cmd +#endif + +int +__fcntl_nocancel (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); + + return __fcntl_nocancel_adjusted (fd, cmd, arg); +} +hidden_def (__fcntl_nocancel) + +int +__fcntl_nocancel_adjusted (int fd, int cmd, void *arg) +{ + if (cmd == F_GETOWN) + { + INTERNAL_SYSCALL_DECL (err); + struct f_owner_ex fex; + int res = INTERNAL_SYSCALL_CALL (fcntl64, err, fd, F_GETOWN_EX, &fex); + if (!INTERNAL_SYSCALL_ERROR_P (res, err)) + return fex.type == F_OWNER_GID ? -fex.pid : fex.pid; + + return INLINE_SYSCALL_ERROR_RETURN_VALUE + (INTERNAL_SYSCALL_ERRNO (res, err)); + } + + return INLINE_SYSCALL_CALL (fcntl64, fd, cmd, (void *) arg); +} diff --git a/sysdeps/unix/sysv/linux/i386/smp.h b/sysdeps/unix/sysv/linux/i386/smp.h index 01734b1779..5457bb27d3 100644 --- a/sysdeps/unix/sysv/linux/i386/smp.h +++ b/sysdeps/unix/sysv/linux/i386/smp.h @@ -41,7 +41,7 @@ is_smp_system (void) else { /* This was not successful. Now try reading the /proc filesystem. */ - int fd = __open_nocancel ("/proc/sys/kernel/version", O_RDONLY); + int fd = __open64_nocancel ("/proc/sys/kernel/version", O_RDONLY); if (__builtin_expect (fd, 0) == -1 || __read_nocancel (fd, u.buf, sizeof (u.buf)) <= 0) /* This also didn't work. We give up and say it's a UP machine. */ diff --git a/sysdeps/unix/sysv/linux/nanosleep.c b/sysdeps/unix/sysv/linux/nanosleep.c index 8945837407..56296046ca 100644 --- a/sysdeps/unix/sysv/linux/nanosleep.c +++ b/sysdeps/unix/sysv/linux/nanosleep.c @@ -1,4 +1,4 @@ -/* Linux high resolution nanosleep implementation. +/* Linux nanosleep syscall implementation. Copyright (C) 2017-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -29,11 +29,3 @@ __nanosleep (const struct timespec *requested_time, } hidden_def (__nanosleep) weak_alias (__nanosleep, nanosleep) - -int -__nanosleep_nocancel (const struct timespec *requested_time, - struct timespec *remaining) -{ - return INLINE_SYSCALL_CALL (nanosleep, requested_time, remaining); -} -hidden_def (__nanosleep_nocancel) diff --git a/sysdeps/unix/sysv/linux/nanosleep_nocancel.c b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c new file mode 100644 index 0000000000..66f3efd09e --- /dev/null +++ b/sysdeps/unix/sysv/linux/nanosleep_nocancel.c @@ -0,0 +1,29 @@ +/* Linux nanosleep syscall implementation -- non-cancellable. + 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 +#include + +int +__nanosleep_nocancel (const struct timespec *requested_time, + struct timespec *remaining) +{ + return INLINE_SYSCALL_CALL (nanosleep, requested_time, remaining); +} +hidden_def (__nanosleep_nocancel) diff --git a/sysdeps/unix/sysv/linux/nios2/Makefile b/sysdeps/unix/sysv/linux/nios2/Makefile index 20910fa013..5688a16c38 100644 --- a/sysdeps/unix/sysv/linux/nios2/Makefile +++ b/sysdeps/unix/sysv/linux/nios2/Makefile @@ -7,7 +7,3 @@ ifeq ($(subdir),misc) sysdep_headers += sys/cachectl.h sysdep_routines += cacheflush endif - -ifeq ($(subdir),nptl) -libpthread-routines := $(filter-out pt-vfork,$(libpthread-routines)) -endif diff --git a/sysdeps/unix/sysv/linux/nios2/pt-vfork.S b/sysdeps/unix/sysv/linux/nios2/pt-vfork.S new file mode 100644 index 0000000000..147427a42d --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/pt-vfork.S @@ -0,0 +1 @@ +# Nios2 does not require a stub for vfork in libpthread. diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h index e6cdd144c2..0b5c955989 100644 --- a/sysdeps/unix/sysv/linux/not-cancel.h +++ b/sysdeps/unix/sysv/linux/not-cancel.h @@ -30,31 +30,24 @@ /* Non cancellable open syscall. */ __typeof (open) __open_nocancel; -libc_hidden_proto (__open_nocancel) /* Non cancellable open syscall (LFS version). */ __typeof (open64) __open64_nocancel; -libc_hidden_proto (__open64_nocancel) /* Non cancellable openat syscall. */ __typeof (openat) __openat_nocancel; -libc_hidden_proto (__openat_nocancel) /* Non cacellable openat syscall (LFS version). */ __typeof (openat64) __openat64_nocancel; -libc_hidden_proto (__openat64_nocancel) /* Non cancellable read syscall. */ __typeof (__read) __read_nocancel; -libc_hidden_proto (__read_nocancel) /* Uncancelable write. */ __typeof (__write) __write_nocancel; -libc_hidden_proto (__write_nocancel) /* Uncancelable close. */ __typeof (__close) __close_nocancel; -libc_hidden_proto (__close_nocancel) /* Non cancellable close syscall that does not also set errno in case of failure. */ @@ -75,18 +68,28 @@ __writev_nocancel_nostatus (int fd, const struct iovec *iov, int iovcnt) /* Uncancelable waitpid. */ __typeof (waitpid) __waitpid_nocancel; -libc_hidden_proto (__waitpid_nocancel) /* Uncancelable pause. */ __typeof (pause) __pause_nocancel; -libc_hidden_proto (__pause_nocancel) /* Uncancelable nanosleep. */ __typeof (__nanosleep) __nanosleep_nocancel; -hidden_proto (__nanosleep_nocancel) /* Uncancelable fcntl. */ __typeof (__fcntl) __fcntl_nocancel; -libc_hidden_proto (__fcntl_nocancel) + +#if IS_IN (libc) || IS_IN (rtld) +hidden_proto (__open_nocancel) +hidden_proto (__open64_nocancel) +hidden_proto (__openat_nocancel) +hidden_proto (__openat64_nocancel) +hidden_proto (__read_nocancel) +hidden_proto (__write_nocancel) +hidden_proto (__close_nocancel) +hidden_proto (__waitpid_nocancel) +hidden_proto (__pause_nocancel) +hidden_proto (__nanosleep_nocancel) +hidden_proto (__fcntl_nocancel) +#endif #endif /* NOT_CANCEL_H */ diff --git a/sysdeps/unix/sysv/linux/open.c b/sysdeps/unix/sysv/linux/open.c index c189e285c9..7f12292b87 100644 --- a/sysdeps/unix/sysv/linux/open.c +++ b/sysdeps/unix/sysv/linux/open.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2017-2018 Free Software Foundation, Inc. +/* Linux open syscall implementation, non-LFS. + Copyright (C) 2017-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Chris Metcalf , 2011. @@ -22,7 +23,6 @@ #include #include -#include #ifndef __OFF_T_MATCHES_OFF64_T @@ -48,25 +48,4 @@ libc_hidden_def (__libc_open) weak_alias (__libc_open, __open) libc_hidden_weak (__open) weak_alias (__libc_open, open) - -# if !IS_IN (rtld) -int -__open_nocancel (const char *file, int oflag, ...) -{ - int mode = 0; - - if (__OPEN_NEEDS_MODE (oflag)) - { - va_list arg; - va_start (arg, oflag); - mode = va_arg (arg, int); - va_end (arg); - } - - return INLINE_SYSCALL_CALL (openat, AT_FDCWD, file, oflag, mode); -} -# else -strong_alias (__libc_open, __open_nocancel) -# endif -libc_hidden_def (__open_nocancel) #endif diff --git a/sysdeps/unix/sysv/linux/open64.c b/sysdeps/unix/sysv/linux/open64.c index 4af5ee2466..55ef658800 100644 --- a/sysdeps/unix/sysv/linux/open64.c +++ b/sysdeps/unix/sysv/linux/open64.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991-2018 Free Software Foundation, Inc. +/* Linux open syscall implementation, LFS. + Copyright (C) 1991-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 @@ -21,7 +22,7 @@ #include #include -#include + #ifdef __OFF_T_MATCHES_OFF64_T # define EXTRA_OPEN_FLAGS 0 @@ -52,34 +53,9 @@ strong_alias (__libc_open64, __open64) libc_hidden_weak (__open64) weak_alias (__libc_open64, open64) -# if !IS_IN (rtld) -int -__open64_nocancel (const char *file, int oflag, ...) -{ - int mode = 0; - - if (__OPEN_NEEDS_MODE (oflag)) - { - va_list arg; - va_start (arg, oflag); - mode = va_arg (arg, int); - va_end (arg); - } - - return INLINE_SYSCALL_CALL (openat, AT_FDCWD, file, oflag | EXTRA_OPEN_FLAGS, - mode); -} -#else -strong_alias (__libc_open64, __open64_nocancel) -#endif -libc_hidden_def (__open64_nocancel) - #ifdef __OFF_T_MATCHES_OFF64_T strong_alias (__libc_open64, __libc_open) strong_alias (__libc_open64, __open) libc_hidden_weak (__open) weak_alias (__libc_open64, open) - -strong_alias (__open64_nocancel, __open_nocancel) -libc_hidden_weak (__open_nocancel) #endif diff --git a/sysdeps/unix/sysv/linux/open64_nocancel.c b/sysdeps/unix/sysv/linux/open64_nocancel.c new file mode 100644 index 0000000000..5d039eada6 --- /dev/null +++ b/sysdeps/unix/sysv/linux/open64_nocancel.c @@ -0,0 +1,54 @@ +/* Linux open syscall implementation, LFS, non-cancellable. + 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 +#include +#include + +#include + +#ifdef __OFF_T_MATCHES_OFF64_T +# define EXTRA_OPEN_FLAGS 0 +#else +# define EXTRA_OPEN_FLAGS O_LARGEFILE +#endif + +int +__open64_nocancel (const char *file, int oflag, ...) +{ + int mode = 0; + + if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); + mode = va_arg (arg, int); + va_end (arg); + } + + return INLINE_SYSCALL_CALL (openat, AT_FDCWD, file, oflag | EXTRA_OPEN_FLAGS, + mode); +} + +hidden_def (__open64_nocancel) + +#ifdef __OFF_T_MATCHES_OFF64_T +strong_alias (__open64_nocancel, __open_nocancel) +hidden_def (__open_nocancel) +#endif diff --git a/sysdeps/unix/sysv/linux/open_nocancel.c b/sysdeps/unix/sysv/linux/open_nocancel.c new file mode 100644 index 0000000000..2ee3e527cb --- /dev/null +++ b/sysdeps/unix/sysv/linux/open_nocancel.c @@ -0,0 +1,46 @@ +/* Linux open syscall implementation, non-LFS, non-cancellable. + 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 +#include +#include + +#include +#include + +#ifndef __OFF_T_MATCHES_OFF64_T + +int +__open_nocancel (const char *file, int oflag, ...) +{ + int mode = 0; + + if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); + mode = va_arg (arg, int); + va_end (arg); + } + + return INLINE_SYSCALL_CALL (openat, AT_FDCWD, file, oflag, mode); +} +hidden_def (__open_nocancel) + +#endif diff --git a/sysdeps/unix/sysv/linux/openat.c b/sysdeps/unix/sysv/linux/openat.c index 9601e617db..d0ad242271 100644 --- a/sysdeps/unix/sysv/linux/openat.c +++ b/sysdeps/unix/sysv/linux/openat.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2005-2018 Free Software Foundation, Inc. +/* Linux openat syscall implementation, non-LFS. + Copyright (C) 2005-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 @@ -19,7 +20,6 @@ #include #include -#include #ifndef __OFF_T_MATCHES_OFF64_T @@ -43,24 +43,4 @@ __libc_openat (int fd, const char *file, int oflag, ...) weak_alias (__libc_openat, __openat) libc_hidden_weak (__openat) weak_alias (__libc_openat, openat) - -# if !IS_IN (rtld) -int -__openat_nocancel (int fd, const char *file, int oflag, ...) -{ - mode_t mode = 0; - if (__OPEN_NEEDS_MODE (oflag)) - { - va_list arg; - va_start (arg, oflag); - mode = va_arg (arg, mode_t); - va_end (arg); - } - - return INLINE_SYSCALL_CALL (openat, fd, file, oflag, mode); -} -# else -strong_alias (__libc_openat, __openat_nocancel) -# endif -libc_hidden_weak (__openat_nocancel) #endif diff --git a/sysdeps/unix/sysv/linux/openat64.c b/sysdeps/unix/sysv/linux/openat64.c index 6f14711df3..536f4f5aff 100644 --- a/sysdeps/unix/sysv/linux/openat64.c +++ b/sysdeps/unix/sysv/linux/openat64.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2007-2018 Free Software Foundation, Inc. +/* Linux openat syscall implementation, LFS. + Copyright (C) 2007-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 @@ -19,7 +20,6 @@ #include #include -#include #ifdef __OFF_T_MATCHES_OFF64_T # define EXTRA_OPEN_FLAGS 0 @@ -49,31 +49,8 @@ strong_alias (__libc_openat64, __openat64) libc_hidden_weak (__openat64) weak_alias (__libc_openat64, openat64) -#if !IS_IN (rtld) -int -__openat64_nocancel (int fd, const char *file, int oflag, ...) -{ - mode_t mode = 0; - if (__OPEN_NEEDS_MODE (oflag)) - { - va_list arg; - va_start (arg, oflag); - mode = va_arg (arg, mode_t); - va_end (arg); - } - - return INLINE_SYSCALL_CALL (openat, fd, file, oflag | EXTRA_OPEN_FLAGS, - mode); -} -#else -strong_alias (__libc_openat64, __openat64_nocancel) -#endif -libc_hidden_def (__openat64_nocancel) - #ifdef __OFF_T_MATCHES_OFF64_T strong_alias (__libc_openat64, __openat) libc_hidden_weak (__openat) weak_alias (__libc_openat64, openat) - -strong_alias (__openat64_nocancel, __openat_nocancel) #endif diff --git a/sysdeps/unix/sysv/linux/openat64_nocancel.c b/sysdeps/unix/sysv/linux/openat64_nocancel.c new file mode 100644 index 0000000000..f3facc3b72 --- /dev/null +++ b/sysdeps/unix/sysv/linux/openat64_nocancel.c @@ -0,0 +1,51 @@ +/* Linux openat syscall implementation, LFS, non-cancellable. + 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 + +#include +#include + +#ifdef __OFF_T_MATCHES_OFF64_T +# define EXTRA_OPEN_FLAGS 0 +#else +# define EXTRA_OPEN_FLAGS O_LARGEFILE +#endif + +int +__openat64_nocancel (int fd, const char *file, int oflag, ...) +{ + mode_t mode = 0; + if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); + mode = va_arg (arg, mode_t); + va_end (arg); + } + + return INLINE_SYSCALL_CALL (openat, fd, file, oflag | EXTRA_OPEN_FLAGS, + mode); +} +hidden_def (__openat64_nocancel) + +#ifdef __OFF_T_MATCHES_OFF64_T +strong_alias (__openat64_nocancel, __openat_nocancel) +hidden_def (__openat_nocancel) +#endif diff --git a/sysdeps/unix/sysv/linux/openat_nocancel.c b/sysdeps/unix/sysv/linux/openat_nocancel.c new file mode 100644 index 0000000000..ac98238cda --- /dev/null +++ b/sysdeps/unix/sysv/linux/openat_nocancel.c @@ -0,0 +1,43 @@ +/* Linux openat syscall implementation, non-LFS, non-cancellable. + 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 + +#include +#include + +#ifndef __OFF_T_MATCHES_OFF64_T + +int +__openat_nocancel (int fd, const char *file, int oflag, ...) +{ + mode_t mode = 0; + if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); + mode = va_arg (arg, mode_t); + va_end (arg); + } + + return INLINE_SYSCALL_CALL (openat, fd, file, oflag, mode); +} +hidden_def (__openat_nocancel) + +#endif diff --git a/sysdeps/unix/sysv/linux/pause.c b/sysdeps/unix/sysv/linux/pause.c index 7c8d9f4861..7b90365b98 100644 --- a/sysdeps/unix/sysv/linux/pause.c +++ b/sysdeps/unix/sysv/linux/pause.c @@ -19,7 +19,6 @@ #include #include #include -#include /* Suspend the process until a signal arrives. This always returns -1 and sets errno to EINTR. */ @@ -33,14 +32,3 @@ __libc_pause (void) #endif } weak_alias (__libc_pause, pause) - -int -__pause_nocancel (void) -{ -#ifdef __NR_pause - return INLINE_SYSCALL_CALL (pause); -#else - return INLINE_SYSCALL_CALL (ppoll, NULL, 0, NULL, NULL); -#endif -} -libc_hidden_def (__pause_nocancel) diff --git a/sysdeps/unix/sysv/linux/pause_nocancel.c b/sysdeps/unix/sysv/linux/pause_nocancel.c new file mode 100644 index 0000000000..322908c8ea --- /dev/null +++ b/sysdeps/unix/sysv/linux/pause_nocancel.c @@ -0,0 +1,33 @@ +/* Linux pause syscall implementation -- non-cancellable. + 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 +#include +#include + +int +__pause_nocancel (void) +{ +#ifdef __NR_pause + return INLINE_SYSCALL_CALL (pause); +#else + return INLINE_SYSCALL_CALL (ppoll, NULL, 0, NULL, NULL); +#endif +} +hidden_def (__pause_nocancel) diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c deleted file mode 100644 index 48198c1150..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2000-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 - -static inline int -fcntl_adjust_cmd (int cmd) -{ - if (cmd >= F_GETLK64 && cmd <= F_SETLKW64) - cmd -= F_GETLK64 - F_GETLK; - return cmd; -} - -#define FCNTL_ADJUST_CMD(__cmd) \ - fcntl_adjust_cmd (__cmd) - -#include diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h index 0fc179a9a1..0956cf04a7 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h @@ -236,4 +236,13 @@ # endif #endif +/* In the PowerPC64 ABI, the unadorned F_GETLK* opcodes should be used + even by largefile64 code. */ +#define FCNTL_ADJUST_CMD(__cmd) \ + ({ int cmd_ = (__cmd); \ + if (cmd_ >= F_GETLK64 && cmd_ <= F_SETLKW64) \ + cmd_ -= F_GETLK64 - F_GETLK; \ + cmd_; }) + + #endif /* linux/powerpc/powerpc64/sysdep.h */ diff --git a/sysdeps/unix/sysv/linux/pthread_getname.c b/sysdeps/unix/sysv/linux/pthread_getname.c index 358682f436..726218b4df 100644 --- a/sysdeps/unix/sysv/linux/pthread_getname.c +++ b/sysdeps/unix/sysv/linux/pthread_getname.c @@ -45,7 +45,7 @@ pthread_getname_np (pthread_t th, char *buf, size_t len) char fname[sizeof (FMT) + 8]; sprintf (fname, FMT, (unsigned int) pd->tid); - int fd = __open_nocancel (fname, O_RDONLY); + int fd = __open64_nocancel (fname, O_RDONLY); if (fd == -1) return errno; diff --git a/sysdeps/unix/sysv/linux/pthread_setname.c b/sysdeps/unix/sysv/linux/pthread_setname.c index 5a8b500128..91b5273480 100644 --- a/sysdeps/unix/sysv/linux/pthread_setname.c +++ b/sysdeps/unix/sysv/linux/pthread_setname.c @@ -46,7 +46,7 @@ pthread_setname_np (pthread_t th, const char *name) char fname[sizeof (FMT) + 8]; sprintf (fname, FMT, (unsigned int) pd->tid); - int fd = __open_nocancel (fname, O_RDWR); + int fd = __open64_nocancel (fname, O_RDWR); if (fd == -1) return errno; diff --git a/sysdeps/unix/sysv/linux/read.c b/sysdeps/unix/sysv/linux/read.c index 33ce38aaba..26d0bed404 100644 --- a/sysdeps/unix/sysv/linux/read.c +++ b/sysdeps/unix/sysv/linux/read.c @@ -18,7 +18,6 @@ #include #include -#include /* Read NBYTES into BUF from FD. Return the number read or -1. */ ssize_t @@ -32,14 +31,3 @@ libc_hidden_def (__read) weak_alias (__libc_read, __read) libc_hidden_def (read) weak_alias (__libc_read, read) - -#if !IS_IN (rtld) -ssize_t -__read_nocancel (int fd, void *buf, size_t nbytes) -{ - return INLINE_SYSCALL_CALL (read, fd, buf, nbytes); -} -#else -strong_alias (__libc_read, __read_nocancel) -#endif -libc_hidden_def (__read_nocancel) diff --git a/sysdeps/unix/sysv/linux/read_nocancel.c b/sysdeps/unix/sysv/linux/read_nocancel.c new file mode 100644 index 0000000000..24699e3e21 --- /dev/null +++ b/sysdeps/unix/sysv/linux/read_nocancel.c @@ -0,0 +1,28 @@ +/* Linux read syscall implementation -- non-cancellable. + 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 +#include + +ssize_t +__read_nocancel (int fd, void *buf, size_t nbytes) +{ + return INLINE_SYSCALL_CALL (read, fd, buf, nbytes); +} +hidden_def (__read_nocancel) diff --git a/sysdeps/unix/sysv/linux/waitpid.c b/sysdeps/unix/sysv/linux/waitpid.c index d1d30fd431..8cf00e4efd 100644 --- a/sysdeps/unix/sysv/linux/waitpid.c +++ b/sysdeps/unix/sysv/linux/waitpid.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991-2018 Free Software Foundation, Inc. +/* Linux waitpid syscall implementation. + Copyright (C) 1991-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 @@ -19,7 +20,6 @@ #include #include #include -#include __pid_t __waitpid (__pid_t pid, int *stat_loc, int options) @@ -32,14 +32,3 @@ __waitpid (__pid_t pid, int *stat_loc, int options) } libc_hidden_def (__waitpid) weak_alias (__waitpid, waitpid) - -__pid_t -__waitpid_nocancel (__pid_t pid, int *stat_loc, int options) -{ -#ifdef __NR_waitpid - return INLINE_SYSCALL_CALL (waitpid, pid, stat_loc, options); -#else - return INLINE_SYSCALL_CALL (wait4, pid, stat_loc, options, NULL); -#endif -} -libc_hidden_def (__waitpid_nocancel) diff --git a/sysdeps/unix/sysv/linux/waitpid_nocancel.c b/sysdeps/unix/sysv/linux/waitpid_nocancel.c new file mode 100644 index 0000000000..ff1ef3d241 --- /dev/null +++ b/sysdeps/unix/sysv/linux/waitpid_nocancel.c @@ -0,0 +1,34 @@ +/* Linux waitpid syscall implementation -- non-cancellable. + 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 +#include +#include +#include + +__pid_t +__waitpid_nocancel (__pid_t pid, int *stat_loc, int options) +{ +#ifdef __NR_waitpid + return INLINE_SYSCALL_CALL (waitpid, pid, stat_loc, options); +#else + return INLINE_SYSCALL_CALL (wait4, pid, stat_loc, options, NULL); +#endif +} +libc_hidden_def (__waitpid_nocancel) diff --git a/sysdeps/unix/sysv/linux/write.c b/sysdeps/unix/sysv/linux/write.c index c96dc6f397..558639d471 100644 --- a/sysdeps/unix/sysv/linux/write.c +++ b/sysdeps/unix/sysv/linux/write.c @@ -18,7 +18,6 @@ #include #include -#include /* Write NBYTES of BUF to FD. Return the number written, or -1. */ ssize_t @@ -32,14 +31,3 @@ weak_alias (__libc_write, __write) libc_hidden_weak (__write) weak_alias (__libc_write, write) libc_hidden_weak (write) - -#if !IS_IN (rtld) -ssize_t -__write_nocancel (int fd, const void *buf, size_t nbytes) -{ - return INLINE_SYSCALL_CALL (write, fd, buf, nbytes); -} -#else -strong_alias (__libc_write, __write_nocancel) -#endif -libc_hidden_def (__write_nocancel) diff --git a/sysdeps/unix/sysv/linux/write_nocancel.c b/sysdeps/unix/sysv/linux/write_nocancel.c new file mode 100644 index 0000000000..6fe1ea2aaa --- /dev/null +++ b/sysdeps/unix/sysv/linux/write_nocancel.c @@ -0,0 +1,28 @@ +/* Linux write syscall implementation -- non-cancellable. + 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 +#include + +ssize_t +__write_nocancel (int fd, const void *buf, size_t nbytes) +{ + return INLINE_SYSCALL_CALL (write, fd, buf, nbytes); +} +hidden_def (__write_nocancel) -- cgit v1.2.3 From 06ab719d30b01da401150068054d3b8ea93dd12f Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Wed, 4 Apr 2018 11:24:15 -0300 Subject: 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. --- ChangeLog | 68 ++++++++++++++++ NEWS | 6 ++ csu/check_fds.c | 2 +- include/fcntl.h | 7 +- io/Makefile | 3 +- io/Versions | 5 +- io/fcntl.h | 11 +++ io/fcntl64.c | 38 +++++++++ login/utmp_file.c | 4 +- manual/llio.texi | 13 ++-- nptl/Makefile | 1 + sysdeps/generic/not-cancel.h | 4 +- sysdeps/mach/hurd/bits/errno.h | 9 +++ sysdeps/mach/hurd/fcntl.c | 5 ++ sysdeps/mach/hurd/i386/libc.abilist | 2 + sysdeps/posix/fdopendir.c | 2 +- sysdeps/posix/opendir.c | 2 +- sysdeps/unix/pt-fcntl.c | 2 +- sysdeps/unix/sysv/linux/Makefile | 4 +- sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/libc.abilist | 2 + sysdeps/unix/sysv/linux/fcntl.c | 90 +++++++++++++++++++--- sysdeps/unix/sysv/linux/fcntl64.c | 63 +++++++++++++++ sysdeps/unix/sysv/linux/fcntl_nocancel.c | 8 +- sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 + sysdeps/unix/sysv/linux/i386/libc.abilist | 2 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist | 2 + sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist | 2 + sysdeps/unix/sysv/linux/microblaze/libc.abilist | 2 + .../unix/sysv/linux/mips/mips32/fpu/libc.abilist | 2 + .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist | 2 + .../unix/sysv/linux/mips/mips64/n32/libc.abilist | 2 + .../unix/sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 + sysdeps/unix/sysv/linux/not-cancel.h | 4 +- .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist | 2 + .../linux/powerpc/powerpc32/nofpu/libc.abilist | 2 + .../sysv/linux/powerpc/powerpc64/libc-le.abilist | 1 + .../unix/sysv/linux/powerpc/powerpc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist | 1 + sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist | 2 + sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/libc.abilist | 2 + sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist | 2 + sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist | 1 + sysdeps/unix/sysv/linux/tst-ofdlocks-compat.c | 84 ++++++++++++++++++++ sysdeps/unix/sysv/linux/tst-ofdlocks.c | 76 ++++++++++++++++++ sysdeps/unix/sysv/linux/x86_64/64/libc.abilist | 1 + sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 51 files changed, 519 insertions(+), 35 deletions(-) create mode 100644 io/fcntl64.c create mode 100644 sysdeps/unix/sysv/linux/fcntl64.c create mode 100644 sysdeps/unix/sysv/linux/tst-ofdlocks-compat.c create mode 100644 sysdeps/unix/sysv/linux/tst-ofdlocks.c (limited to 'include/fcntl.h') diff --git a/ChangeLog b/ChangeLog index eaee727677..2eeeabf2ad 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 db7c1291fd..9d6fc08eb3 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 605ee4f3f4..ad1763b398 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 966f797890..be435047bc 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 2117cb6b62..4a0d8fea09 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 4448b7197c..98037fbbfc 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 69a4394191..3afc62011a 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 0000000000..f4e6809abc --- /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 72dd21387c..040a505711 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 82f03be2be..e840c55f86 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 6cfc8c60ee..0f9c44afa0 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 19ad8cbc4c..d9f8a75dbd 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 8096fb9c05..bb8b8b669f 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 0b231645c5..598317d811 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 2cb507052b..3d46de795d 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 dafb5d20c1..b72eecc66b 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 0875385f65..bb6bd7cc85 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 8113d52b86..3d64054dd0 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 215fd5d136..f71cc39c7e 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 80cdb98e1c..884d0dfa95 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 c761f61c43..28d54b9794 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 6aa58c3ca7..dfde3bd725 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 e3992dc9d4..cbab7b401a 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 0000000000..f21667ae43 --- /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 f50e382c4a..dd336b5679 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 d10695b7d3..06b00f730a 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 23092ab6d7..1c1cc00d40 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 7bf259e86c..f6e17a005f 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 4673bcd79b..ee054a618d 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 1f8ac40399..227a0581cb 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 09277f5954..18781b3017 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 f562e20f23..2d86989cf2 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 ceb7388829..b8b113e1a5 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 5765f487a2..6a3cd13e2d 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 a84bb45a38..596ec05379 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 e43295986c..8da18eed57 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 0b5c955989..09de92dee9 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 a5f2b23068..555751eb12 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 e4cbe36279..80324e41aa 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 9869feb56b..97b1d354af 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 e526dc4627..15be314921 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 e6319eef8d..436b992251 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 41cdda0c2e..f66715f0c9 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 8a756cf287..bd6242861b 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 999bddd1db..f2f070fbce 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 7c4296fc10..265087f6a8 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 dafe9d74b7..16a69812cb 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 0000000000..d1d00eb3fb --- /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 0000000000..bd345e9b64 --- /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 f72d494920..fa8c198d13 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 96c9fa050e..2536971682 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 -- cgit v1.2.3