Skip to content
Permalink
Browse files
DO NOT MERGE: [glibc] Treat EPERM like ENOSYS on *time64 syscalls
Newer glibc running in some outdated, constrained hosts (such as Docker containers)
will receive EPERM when executing various time-related syscalls.

The issue is host-side, and due to libseccomp not being aware of the new syscalls.
Glibc does the correct thing here, but unfortunately this prevents time-related
syscalls to work on older hosts (such as some CI providers).

This patch allows glibc to fallback to the older syscalls even when EPERM has
been returned.

Signed-off-by: Eugenio Paolantonio (g7) <me@medesimo.eu>
  • Loading branch information
g7 committed Dec 7, 2020
1 parent d5268a8 commit 0c45d4564fb3daf06d6737d583c4a5c7fb900692
Show file tree
Hide file tree
Showing 9 changed files with 9 additions and 9 deletions.
@@ -52,7 +52,7 @@ __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
# else
r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
# endif
if (r == 0 || errno != ENOSYS)
if (r == 0 || ! (errno == ENOSYS || errno == EPERM))
return r;

atomic_store_relaxed (&time64_support, 0);
@@ -53,7 +53,7 @@ __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
# else
r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
# endif
if (r == 0 || errno != ENOSYS)
if (r == 0 || ! (errno == ENOSYS || errno == EPERM))
return r;

atomic_store_relaxed (&time64_support, 0);
@@ -54,7 +54,7 @@ __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec

if (! INTERNAL_SYSCALL_ERROR_P (r, err))
return 0;
if (INTERNAL_SYSCALL_ERRNO (r, err) != ENOSYS)
if (! (INTERNAL_SYSCALL_ERRNO (r, err) == ENOSYS || INTERNAL_SYSCALL_ERRNO (r, err) == EPERM))
return INTERNAL_SYSCALL_ERRNO (r, err);
# endif /* __NR_clock_nanosleep_time64 */

@@ -40,7 +40,7 @@ __clock_settime64 (clockid_t clock_id, const struct __timespec64 *tp)
#else
# ifdef __NR_clock_settime64
int ret = INLINE_SYSCALL_CALL (clock_settime64, clock_id, tp);
if (ret == 0 || errno != ENOSYS)
if (ret == 0 || ! (errno == ENOSYS || errno == EPERM))
return ret;
# endif
if (! in_time_t_range (tp->tv_sec))
@@ -46,7 +46,7 @@ __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
# ifdef __NR_ppoll_time64
int ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
_NSIG / 8);
if (ret >= 0 || errno != ENOSYS)
if (ret >= 0 || ! (errno == ENOSYS || errno == EPERM))
return ret;
# endif
struct timespec ts32;
@@ -30,7 +30,7 @@ statx (int fd, const char *path, int flags,
# ifdef __ASSUME_STATX
return ret;
# else
if (ret == 0 || errno != ENOSYS)
if (ret == 0 || ! (errno == ENOSYS || errno == EPERM))
/* Preserve non-error/non-ENOSYS return values. */
return ret;
# endif
@@ -36,7 +36,7 @@ __timer_gettime64 (timer_t timerid, struct __itimerspec64 *value)
#else
# ifdef __NR_timer_gettime64
int ret = INLINE_SYSCALL_CALL (timer_gettime64, kt->ktimerid, value);
if (ret == 0 || errno != ENOSYS)
if (ret == 0 || ! (errno == ENOSYS || errno == EPERM))
return ret;
# endif
struct itimerspec its32;
@@ -40,7 +40,7 @@ __timer_settime64 (timer_t timerid, int flags,
# ifdef __NR_timer_settime64
int ret = INLINE_SYSCALL_CALL (timer_settime64, kt->ktimerid, flags, value,
ovalue);
if (ret == 0 || errno != ENOSYS)
if (ret == 0 || ! (errno == ENOSYS || errno == EPERM))
return ret;
# endif
struct itimerspec its32, oits32;
@@ -36,7 +36,7 @@ __utimensat64_helper (int fd, const char *file,
#else
# ifdef __NR_utimensat_time64
int ret = INLINE_SYSCALL (utimensat_time64, 4, fd, file, &tsp64[0], flags);
if (ret == 0 || errno != ENOSYS)
if (ret == 0 || ! (errno == ENOSYS || errno == EPERM))
return ret;
# endif
if (tsp64

0 comments on commit 0c45d45

Please sign in to comment.