glib/gthread-posix: Block futex_time64 usage on Android API level < 30

This syscall is seccomp blocked on all lower API levels:

ee7bc3002d
This commit is contained in:
L. E. Segovia 2024-04-01 23:55:01 -03:00
parent e9cd534a14
commit 06ea9aed58
2 changed files with 43 additions and 3 deletions

View File

@ -1605,12 +1605,16 @@ g_cond_wait_until (GCond *cond,
* To get around this problem we
* a) check if `futex_time64` is available, which only exists on 32-bit
* platforms and always uses 64-bit `time_t`.
* b) otherwise (or if that returns `ENOSYS`), we call the normal `futex`
* b) if `futex_time64` is available, but the Android runtime's API level
* is < 30, `futex_time64` is blocked by seccomp and using it will cause
* the app to be terminated. Skip to c).
* https://android-review.googlesource.com/c/platform/bionic/+/1094758
* c) otherwise (or if that returns `ENOSYS`), we call the normal `futex`
* syscall with the `struct timespec` used by the kernel. By default, we
* use `__kernel_long_t` for both its fields, which is equivalent to
* `__kernel_old_time_t` and is available in the kernel headers for a
* longer time.
* c) With very old headers (~2.6.x), `__kernel_long_t` is not available, and
* d) With very old headers (~2.6.x), `__kernel_long_t` is not available, and
* we use an older definition that uses `__kernel_time_t` and `long`.
*
* Also some 32-bit systems do not define `__NR_futex` at all and only
@ -1621,7 +1625,11 @@ g_cond_wait_until (GCond *cond,
g_mutex_unlock (mutex);
#ifdef __NR_futex_time64
#if defined(__BIONIC__)
if (__builtin_available (android 30, *)) {
#else
{
#endif
struct
{
gint64 tv_sec;

View File

@ -64,10 +64,41 @@ struct _GRealThread
* with the normal `futex` syscall. This can happen if newer kernel headers
* are used than the kernel that is actually running.
*
* The `futex_time64` syscall is also skipped in favour of `futex` if the
* Android runtimes API level is lower than 30, as its blocked by seccomp
* there and using it will cause the app to be terminated:
* https://android-review.googlesource.com/c/platform/bionic/+/1094758
* https://github.com/aosp-mirror/platform_bionic/commit/ee7bc3002dc3127faac110167d28912eb0e86a20
*
* This must not be called with a timeout parameter as that differs
* in size between the two syscall variants!
*/
#if defined(__NR_futex) && defined(__NR_futex_time64)
#if defined(__BIONIC__)
#define g_futex_simple(uaddr, futex_op, ...) \
G_STMT_START \
{ \
int res = 0; \
if (__builtin_available (android 30, *)) \
{ \
res = syscall (__NR_futex_time64, uaddr, (gsize) futex_op, __VA_ARGS__); \
if (res < 0 && errno == ENOSYS) \
{ \
errno = saved_errno; \
res = syscall (__NR_futex, uaddr, (gsize) futex_op, __VA_ARGS__); \
} \
} \
else \
{ \
res = syscall (__NR_futex, uaddr, (gsize) futex_op, __VA_ARGS__); \
} \
if (res < 0 && errno == EAGAIN) \
{ \
errno = saved_errno; \
} \
} \
G_STMT_END
#else
#define g_futex_simple(uaddr, futex_op, ...) \
G_STMT_START \
{ \
@ -84,6 +115,7 @@ struct _GRealThread
} \
} \
G_STMT_END
#endif /* defined(__BIONIC__) */
#elif defined(__NR_futex_time64)
#define g_futex_simple(uaddr, futex_op, ...) \
G_STMT_START \
@ -109,7 +141,7 @@ struct _GRealThread
} \
G_STMT_END
#else /* !defined(__NR_futex) && !defined(__NR_futex_time64) */
#error "Neither __NR_futex nor __NR_futex_time64 are defined but were found by meson"
#error "Neither __NR_futex nor __NR_futex_time64 are available"
#endif /* defined(__NR_futex) && defined(__NR_futex_time64) */
#endif