Commit Graph

4 Commits

Author SHA1 Message Date
Zack Weinberg
329ea513b4 Avoid cancellable I/O primitives in ld.so.
Neither the <dlfcn.h> 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.
2018-06-12 09:53:04 -04:00
Joseph Myers
688903eb3e Update copyright dates with scripts/update-copyrights.
* All files with FSF copyright notices: Update copyright dates
	using scripts/update-copyrights.
	* locale/programs/charmap-kw.h: Regenerated.
	* locale/programs/locfile-kw.h: Likewise.
2018-01-01 00:32:25 +00:00
Adhemerval Zanella
c22845744c Consolidate non cancellable open call
This patch consolidates all the non cancellable open calls to use
the __open_nocancel identifier.  For non cancellable targets it will
be just a macro to call the default respective symbol while on Linux
will be a internal one.

To be consistent with the following non cancellable openat call, a
new __open64_nocancel is also added (although not currently used).

Checked on x86_64-linux-gnu, x86_64-linux-gnu-x32, and i686-linux-gnu.

	* sysdeps/generic/not-cancel.h (open_not_cancel): Remove macro.
	(open_not_cancel_2): Likewise.
	(open_nocancel): New macro.
	(open64_nocancel): Likewise.
	* sysdeps/unix/sysv/linux/not-cancel.h (open_not_cancel): Remove macro.
	(open_not_cancel_2): Likewise.
	(__open_nocancel): New prototype.
	(__open64_nocancel): Likewise.
	* sysdeps/unix/sysv/linux/Versions (libc) [GLIBC_PRIVATE]: Add
	__open_nocancel.
	* sysdeps/unix/sysv/linux/open.c (__open_nocancel): New function.
	* sysdeps/unix/sysv/linux/open64.c (__open64_nocancel): Likewise.
	* catgets/open_catalog.c (__open_catalog): Replace open_not_cancel{_2}
	with __open_nocancel.
	* csu/check_fds.c (check_one_fd): Likewise.
	* gmon/gmon.c (write_gmon): Likewise.
	* iconv/gconv_cache.c (__gconv_load_cached): Likewise.
	* intl/loadmsgcat.c (open): Likewise.
	* libio/fileops.c (_IO_file_open): Likewise.
	* locale/loadarchive.c (_nl_load_locale_from_archive): Likewise.
	* locale/loadlocale.c (_nl_load_locale): Likewise.
	* login/utmp_file.c (setutent_file): Likewise.
	* misc/daemon.c (daemon): Likewise.
	* nss/nss_db/db-open.c (internal_setent): Likewise.
	* sysdeps/mach/hurd/opendir.c (__opendirat): Likewise.
	* sysdeps/posix/libc_fatal.c (__libc_message): Likewise.
	* sysdeps/posix/opendir.c (tryopen_o_directory): Likewise.
	(__opendir): Likewise.
	* sysdeps/posix/spawni.c (__spawni_child): Likewise.
	* sysdeps/unix/sysv/linux/fips-private.h (fips_enable_p): Likewise.
	* sysdeps/unix/sysv/linux/gethostid.c (sethostid): Likewise.
	(gethostid): Likewise.
	* sysdeps/unix/sysv/linux/getloadavg.c (getloadavg): Likewise.
	* sysdeps/unix/sysv/linux/getlogin_r.c (__getlogin_r_loginuid):
	Likewise.
	* sysdeps/unix/sysv/linux/getsysstats.c (__get_nprocs): Likewise.
	* sysdeps/unix/sysv/linux/grantpt.c (__close_all_fds): Likewise.
	* sysdeps/unix/sysv/linux/i386/smp.h (is_smp_system): Likewise.
	* sysdeps/unix/sysv/linux/ia64/has_cpuclock.c (has_cpuclock):
	Likewise.
	* sysdeps/unix/sysv/linux/libc_fatal.c (backtrace_and_maps):
	Likewise.
	* sysdeps/unix/sysv/linux/malloc-sysdep.h (check_may_shrink_heap):
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c (__get_clockfreq):
	Likewise.
	* sysdeps/unix/sysv/linux/pthread_getname.c (pthread_getname_np):
	Likewise.
	* sysdeps/unix/sysv/linux/pthread_setname.c (pthread_setname_np):
	Likewise.
	* sysdeps/unix/sysv/linux/spawni.c (__spawni_child): Likewise.
	* sysdeps/unix/sysv/linux/sysconf.c (__sysconf): Likewise.
2017-08-17 16:50:35 -03:00
Adhemerval Zanella
b41152d716 Consolidate Linux open implementation
This patch consolidates the open Linux syscall implementation on
sysdeps/unix/sysv/linux/open{64}.c.  The changes are:

  1. Remove open{64} from auto-generation syscalls.list.
  2. Add a new open{64}.c implementation.  For architectures that
     define __OFF_T_MATCHES_OFF64_T the default open64 will create
     alias to required open symbols.
  3. Use __NR_openat as default syscall for open{64}.

Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32,
arch64-linux-gnu, arm-linux-gnueabihf, and powerpc64le-linux-gnu.

	* sysdeps/unix/sysv/linux/generic/open.c: Remove file.
	* sysdeps/unix/sysv/linux/generic/open64.c: Likewise.
	* sysdeps/unix/sysv/linux/wordsize-64/open64.c: Likewise.
	* sysdeps/unix/sysv/linux/open.c: New file.
	* sysdeps/unix/sysv/linux/open64.c (__libc_open64): Use O_LARGEFILE
	only for __OFF_T_MATCHES_OFF64_T and add alias to open if the case.
	* sysdeps/unix/sysv/linux/wordsize-64/syscalls.list: Remove open
	from auto-generated list.
2017-05-11 15:49:10 -03:00