musl/src/select/select.c, branch master musl - an implementation of the standard library for Linux-based systems select: fix 64-bit timeout truncation on pre-time64 kernels 2023年03月03日T01:00:45+00:00 Alexey Izbyshev izbyshev@ispras.ru 2023年03月02日T05:10:47+00:00 8949da7ab1c0dbf801e8bc78f0c0adc625020f75 If the (normalized) timeout passed to select exceeds INT_MAX seconds on an arch with SYS_pselect6_time64 and the kernel is too old to support time64 syscalls, the timeout is implicitly converted to (32-bit) long on the fallback path, losing its upper 32 bits and potentially becoming a small positive value, violating the intended semantics, or even a negative value, causing the fallback syscall failure. Fix this by saturating the timeout at INT_MAX as done in other time64 fallback cases.
If the (normalized) timeout passed to select exceeds INT_MAX seconds on
an arch with SYS_pselect6_time64 and the kernel is too old to support
time64 syscalls, the timeout is implicitly converted to (32-bit) long on
the fallback path, losing its upper 32 bits and potentially becoming a
small positive value, violating the intended semantics, or even
a negative value, causing the fallback syscall failure. Fix this by
saturating the timeout at INT_MAX as done in other time64 fallback
cases.
fix regression in select with no timeout 2019年08月07日T06:57:53+00:00 Rich Felker dalias@aerifal.cx 2019年08月07日T06:57:53+00:00 d0b547dfb5f7678cab6bc39dd736ed6454357ca4 commit 722a1ae3351a03ab25010dbebd492eced664853b inadvertently passed a copy of {s,us} to the syscall even if the timeout argument tv was null, thereby causing immediate timeout (polling) in place of unlimited timeout. only archs using SYS_select were affected.
commit 722a1ae3351a03ab25010dbebd492eced664853b inadvertently passed a
copy of {s,us} to the syscall even if the timeout argument tv was
null, thereby causing immediate timeout (polling) in place of
unlimited timeout. only archs using SYS_select were affected.
select: overhaul for time64 2019年07月30日T18:23:56+00:00 Rich Felker dalias@aerifal.cx 2019年07月30日T01:08:43+00:00 722a1ae3351a03ab25010dbebd492eced664853b major changes are made alongside adding time64 syscall support to account for issues found during research. select historically accepts non-normalized (tv_usec not restricted to less than 1000000) timeouts, and the kernel normalizes them, but the normalization code is buggy and subject to integer overflows. since normalization is needed anyway when using SYS_pselect6 or SYS_pselect6_time64 as the backend, simply do it up-front to eliminate both code path complexity and the possibility of kernel bugs. as a side effect, select no longer updates the caller's timeout timeval with the remaining time. previously, archs that used SYS_select updated it and archs that used SYS_pselect6 didn't. this change may turn out to be controversial and may need revisiting, but in any case the old behavior was not strictly conforming. POSIX allows modification of the timeout "upon successful completion", but the Linux syscall modifies it upon unsuccessful completion (EINTR) as well (and presumably each time the syscall stops and restarts before it's known whether completion will be successful). it's possible that this language does not reflect the actual intent of the standard, since other historical implementations probably behaved like Linux, but that should be clarified if there's a desire to bring the old behavior back. regardless, programs that are depending on this are not correct and are already broken on some archs we support.
major changes are made alongside adding time64 syscall support to
account for issues found during research. select historically accepts
non-normalized (tv_usec not restricted to less than 1000000) timeouts,
and the kernel normalizes them, but the normalization code is buggy
and subject to integer overflows. since normalization is needed anyway
when using SYS_pselect6 or SYS_pselect6_time64 as the backend, simply
do it up-front to eliminate both code path complexity and the
possibility of kernel bugs.
as a side effect, select no longer updates the caller's timeout
timeval with the remaining time. previously, archs that used
SYS_select updated it and archs that used SYS_pselect6 didn't. this
change may turn out to be controversial and may need revisiting, but
in any case the old behavior was not strictly conforming.
POSIX allows modification of the timeout "upon successful completion",
but the Linux syscall modifies it upon unsuccessful completion (EINTR)
as well (and presumably each time the syscall stops and restarts
before it's known whether completion will be successful). it's
possible that this language does not reflect the actual intent of the
standard, since other historical implementations probably behaved like
Linux, but that should be clarified if there's a desire to bring the
old behavior back. regardless, programs that are depending on this are
not correct and are already broken on some archs we support.
reduce spurious inclusion of libc.h 2018年09月12日T18:34:37+00:00 Rich Felker dalias@aerifal.cx 2018年09月12日T04:08:09+00:00 5ce3737931bb411a8d167356d4d0287b53b0cbdc libc.h was intended to be a header for access to global libc state and related interfaces, but ended up included all over the place because it was the way to get the weak_alias macro. most of the inclusions removed here are places where weak_alias was needed. a few were recently introduced for hidden. some go all the way back to when libc.h defined CANCELPT_BEGIN and _END, and all (wrongly implemented) cancellation points had to include it. remaining spurious users are mostly callers of the LOCK/UNLOCK macros and files that use the LFS64 macro to define the awful *64 aliases. in a few places, new inclusion of libc.h is added because several internal headers no longer implicitly include libc.h. declarations for __lockfile and __unlockfile are moved from libc.h to stdio_impl.h so that the latter does not need libc.h. putting them in libc.h made no sense at all, since the macros in stdio_impl.h are needed to use them correctly anyway.
libc.h was intended to be a header for access to global libc state and
related interfaces, but ended up included all over the place because
it was the way to get the weak_alias macro. most of the inclusions
removed here are places where weak_alias was needed. a few were
recently introduced for hidden. some go all the way back to when
libc.h defined CANCELPT_BEGIN and _END, and all (wrongly implemented)
cancellation points had to include it.
remaining spurious users are mostly callers of the LOCK/UNLOCK macros
and files that use the LFS64 macro to define the awful *64 aliases.
in a few places, new inclusion of libc.h is added because several
internal headers no longer implicitly include libc.h.
declarations for __lockfile and __unlockfile are moved from libc.h to
stdio_impl.h so that the latter does not need libc.h. putting them in
libc.h made no sense at all, since the macros in stdio_impl.h are
needed to use them correctly anyway.
support linux kernel apis (new archs) with old syscalls removed 2014年05月30日T01:01:32+00:00 Rich Felker dalias@aerifal.cx 2014年05月30日T01:01:32+00:00 dd5f50da6f6c3df5647e922e47f8568a8896a752 such archs are expected to omit definitions of the SYS_* macros for syscalls their kernels lack from arch/$ARCH/bits/syscall.h. the preprocessor is then able to select the an appropriate implementation for affected functions. two basic strategies are used on a case-by-case basis: where the old syscalls correspond to deprecated library-level functions, the deprecated functions have been converted to wrappers for the modern function, and the modern function has fallback code (omitted at the preprocessor level on new archs) to make use of the old syscalls if the new syscall fails with ENOSYS. this also improves functionality on older kernels and eliminates the incentive to program with deprecated library-level functions for the sake of compatibility with older kernels. in other situations where the old syscalls correspond to library-level functions which are not deprecated but merely lack some new features, such as the *at functions, the old syscalls are still used on archs which support them. this may change at some point in the future if or when fallback code is added to the new functions to make them usable (possibly with reduced functionality) on old kernels.
such archs are expected to omit definitions of the SYS_* macros for
syscalls their kernels lack from arch/$ARCH/bits/syscall.h. the
preprocessor is then able to select the an appropriate implementation
for affected functions. two basic strategies are used on a
case-by-case basis:
where the old syscalls correspond to deprecated library-level
functions, the deprecated functions have been converted to wrappers
for the modern function, and the modern function has fallback code
(omitted at the preprocessor level on new archs) to make use of the
old syscalls if the new syscall fails with ENOSYS. this also improves
functionality on older kernels and eliminates the incentive to program
with deprecated library-level functions for the sake of compatibility
with older kernels.
in other situations where the old syscalls correspond to library-level
functions which are not deprecated but merely lack some new features,
such as the *at functions, the old syscalls are still used on archs
which support them. this may change at some point in the future if or
when fallback code is added to the new functions to make them usable
(possibly with reduced functionality) on old kernels.
use restrict everywhere it's required by c99 and/or posix 2008 2012年09月07日T02:44:55+00:00 Rich Felker dalias@aerifal.cx 2012年09月07日T02:44:55+00:00 400c5e5c8307a2ebe44ef1f203f5a15669f20347 to deal with the fact that the public headers may be used with pre-c99 compilers, __restrict is used in place of restrict, and defined appropriately for any supported compiler. we also avoid the form [restrict] since older versions of gcc rejected it due to a bug in the original c99 standard, and instead use the form *restrict.
to deal with the fact that the public headers may be used with pre-c99
compilers, __restrict is used in place of restrict, and defined
appropriately for any supported compiler. we also avoid the form
[restrict] since older versions of gcc rejected it due to a bug in the
original c99 standard, and instead use the form *restrict.
overhaul pthread cancellation 2011年04月17日T15:43:03+00:00 Rich Felker dalias@aerifal.cx 2011年04月17日T15:43:03+00:00 feee98903cd8119d9a3db62589246a940f44a9f5 this patch improves the correctness, simplicity, and size of cancellation-related code. modulo any small errors, it should now be completely conformant, safe, and resource-leak free. the notion of entering and exiting cancellation-point context has been completely eliminated and replaced with alternative syscall assembly code for cancellable syscalls. the assembly is responsible for setting up execution context information (stack pointer and address of the syscall instruction) which the cancellation signal handler can use to determine whether the interrupted code was in a cancellable state. these changes eliminate race conditions in the previous generation of cancellation handling code (whereby a cancellation request received just prior to the syscall would not be processed, leaving the syscall to block, potentially indefinitely), and remedy an issue where non-cancellable syscalls made from signal handlers became cancellable if the signal handler interrupted a cancellation point. x86_64 asm is untested and may need a second try to get it right.
this patch improves the correctness, simplicity, and size of
cancellation-related code. modulo any small errors, it should now be
completely conformant, safe, and resource-leak free.
the notion of entering and exiting cancellation-point context has been
completely eliminated and replaced with alternative syscall assembly
code for cancellable syscalls. the assembly is responsible for setting
up execution context information (stack pointer and address of the
syscall instruction) which the cancellation signal handler can use to
determine whether the interrupted code was in a cancellable state.
these changes eliminate race conditions in the previous generation of
cancellation handling code (whereby a cancellation request received
just prior to the syscall would not be processed, leaving the syscall
to block, potentially indefinitely), and remedy an issue where
non-cancellable syscalls made from signal handlers became cancellable
if the signal handler interrupted a cancellation point.
x86_64 asm is untested and may need a second try to get it right.
overhaul cancellation to fix resource leaks and dangerous behavior with signals 2011年03月24日T18:18:00+00:00 Rich Felker dalias@aerifal.cx 2011年03月24日T18:18:00+00:00 b470030f839a375e5030ec9d44903ef7581c15a2 this commit addresses two issues: 1. a race condition, whereby a cancellation request occurring after a syscall returned from kernelspace but before the subsequent CANCELPT_END would cause cancellable resource-allocating syscalls (like open) to leak resources. 2. signal handlers invoked while the thread was blocked at a cancellation point behaved as if asynchronous cancellation mode wer in effect, resulting in potentially dangerous state corruption if a cancellation request occurs. the glibc/nptl implementation of threads shares both of these issues. with this commit, both are fixed. however, cancellation points encountered in a signal handler will not be acted upon if the signal was received while the thread was already at a cancellation point. they will of course be acted upon after the signal handler returns, so in real-world usage where signal handlers quickly return, it should not be a problem. it's possible to solve this problem too by having sigaction() wrap all signal handlers with a function that uses a pthread_cleanup handler to catch cancellation, patch up the saved context, and return into the cancellable function that will catch and act upon the cancellation. however that would be a lot of complexity for minimal if any benefit...
this commit addresses two issues:
1. a race condition, whereby a cancellation request occurring after a
syscall returned from kernelspace but before the subsequent
CANCELPT_END would cause cancellable resource-allocating syscalls
(like open) to leak resources.
2. signal handlers invoked while the thread was blocked at a
cancellation point behaved as if asynchronous cancellation mode wer in
effect, resulting in potentially dangerous state corruption if a
cancellation request occurs.
the glibc/nptl implementation of threads shares both of these issues.
with this commit, both are fixed. however, cancellation points
encountered in a signal handler will not be acted upon if the signal
was received while the thread was already at a cancellation point.
they will of course be acted upon after the signal handler returns, so
in real-world usage where signal handlers quickly return, it should
not be a problem. it's possible to solve this problem too by having
sigaction() wrap all signal handlers with a function that uses a
pthread_cleanup handler to catch cancellation, patch up the saved
context, and return into the cancellable function that will catch and
act upon the cancellation. however that would be a lot of complexity
for minimal if any benefit...
global cleanup to use the new syscall interface 2011年03月20日T04:16:43+00:00 Rich Felker dalias@aerifal.cx 2011年03月20日T04:16:43+00:00 aa398f56fa398f2202b04e82c67f822f3233786f
yet another ugly legacy syscall rename... 2011年02月15日T10:52:27+00:00 Rich Felker dalias@aerifal.cx 2011年02月15日T10:52:27+00:00 c2afb747b0296f23cd1903e82ccbdee3fc2978fd

AltStyle によって変換されたページ (->オリジナル) /