libstdc++: Avoid 32-bit time_t overflows in futex calls
authorJonathan Wakely <jwakely@redhat.com>
Fri, 13 Nov 2020 15:19:04 +0000 (15:19 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Fri, 13 Nov 2020 17:19:12 +0000 (17:19 +0000)
commite7e0eeeb6e6707be2a6c6da49d4b6be3199e2af8
treeb3cb57da78e250150b9f926a4e7a9b3e87ad1418
parent0d1189b4e618517b62f938a94c722123cc0ef5f5
libstdc++: Avoid 32-bit time_t overflows in futex calls

The existing code doesn't check whether the chrono::seconds value is out
of range of time_t. When using a timeout before the epoch (with a
negative value) subtracting the current time (as time_t) and then
assigning it to a time_t can overflow to a large positive value. This
means that we end up waiting several years even though the specific
timeout was in the distant past.

We do have a check for negative timeouts, but that happens after the
conversion to time_t so happens after the overflow.

The conversion to a relative timeout is done in two places, so this
factors it into a new function and adds the overflow checks there.

libstdc++-v3/ChangeLog:

* src/c++11/futex.cc (relative_timespec): New function to
create relative time from two absolute times.
(__atomic_futex_unsigned_base::_M_futex_wait_until)
(__atomic_futex_unsigned_base::_M_futex_wait_until_steady):
Use relative_timespec.
libstdc++-v3/src/c++11/futex.cc