mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-23 20:46:14 +01:00
Merge branch 'fix-futex-time64-usage-android-30' into 'main'
glib/gthread-posix: Block futex_time64 usage on Android API level < 30 See merge request GNOME/glib!3987
This commit is contained in:
commit
b907e28454
@ -1605,12 +1605,16 @@ g_cond_wait_until (GCond *cond,
|
|||||||
* To get around this problem we
|
* To get around this problem we
|
||||||
* a) check if `futex_time64` is available, which only exists on 32-bit
|
* a) check if `futex_time64` is available, which only exists on 32-bit
|
||||||
* platforms and always uses 64-bit `time_t`.
|
* 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
|
* syscall with the `struct timespec` used by the kernel. By default, we
|
||||||
* use `__kernel_long_t` for both its fields, which is equivalent to
|
* 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
|
* `__kernel_old_time_t` and is available in the kernel headers for a
|
||||||
* longer time.
|
* 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`.
|
* 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
|
* Also some 32-bit systems do not define `__NR_futex` at all and only
|
||||||
@ -1620,8 +1624,12 @@ g_cond_wait_until (GCond *cond,
|
|||||||
sampled = cond->i[0];
|
sampled = cond->i[0];
|
||||||
g_mutex_unlock (mutex);
|
g_mutex_unlock (mutex);
|
||||||
|
|
||||||
#ifdef __NR_futex_time64
|
#if defined(HAVE_FUTEX_TIME64)
|
||||||
|
#if defined(__BIONIC__)
|
||||||
|
if (__builtin_available (android 30, *)) {
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
|
#endif
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
gint64 tv_sec;
|
gint64 tv_sec;
|
||||||
@ -1637,9 +1645,9 @@ g_cond_wait_until (GCond *cond,
|
|||||||
* normal `futex` syscall. This can happen if newer kernel headers are
|
* normal `futex` syscall. This can happen if newer kernel headers are
|
||||||
* used than the kernel that is actually running.
|
* used than the kernel that is actually running.
|
||||||
*/
|
*/
|
||||||
# ifdef __NR_futex
|
# if defined(HAVE_FUTEX)
|
||||||
if (res >= 0 || errno != ENOSYS)
|
if (res >= 0 || errno != ENOSYS)
|
||||||
# endif /* defined(__NR_futex) */
|
# endif /* defined(HAVE_FUTEX) */
|
||||||
{
|
{
|
||||||
success = (res < 0 && errno == ETIMEDOUT) ? FALSE : TRUE;
|
success = (res < 0 && errno == ETIMEDOUT) ? FALSE : TRUE;
|
||||||
g_mutex_lock (mutex);
|
g_mutex_lock (mutex);
|
||||||
@ -1649,7 +1657,7 @@ g_cond_wait_until (GCond *cond,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NR_futex
|
#if defined(HAVE_FUTEX)
|
||||||
{
|
{
|
||||||
# ifdef __kernel_long_t
|
# ifdef __kernel_long_t
|
||||||
# define KERNEL_SPAN_SEC_TYPE __kernel_long_t
|
# define KERNEL_SPAN_SEC_TYPE __kernel_long_t
|
||||||
@ -1681,7 +1689,7 @@ g_cond_wait_until (GCond *cond,
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
# undef KERNEL_SPAN_SEC_TYPE
|
# undef KERNEL_SPAN_SEC_TYPE
|
||||||
#endif /* defined(__NR_futex) */
|
#endif /* defined(HAVE_FUTEX) */
|
||||||
|
|
||||||
/* We can't end up here because of the checks above */
|
/* We can't end up here because of the checks above */
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
@ -64,10 +64,41 @@ struct _GRealThread
|
|||||||
* with the normal `futex` syscall. This can happen if newer kernel headers
|
* with the normal `futex` syscall. This can happen if newer kernel headers
|
||||||
* are used than the kernel that is actually running.
|
* are used than the kernel that is actually running.
|
||||||
*
|
*
|
||||||
|
* The `futex_time64` syscall is also skipped in favour of `futex` if the
|
||||||
|
* Android runtime’s API level is lower than 30, as it’s 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
|
* This must not be called with a timeout parameter as that differs
|
||||||
* in size between the two syscall variants!
|
* in size between the two syscall variants!
|
||||||
*/
|
*/
|
||||||
#if defined(__NR_futex) && defined(__NR_futex_time64)
|
#if defined(HAVE_FUTEX) && defined(HAVE_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, ...) \
|
#define g_futex_simple(uaddr, futex_op, ...) \
|
||||||
G_STMT_START \
|
G_STMT_START \
|
||||||
{ \
|
{ \
|
||||||
@ -84,7 +115,8 @@ struct _GRealThread
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
G_STMT_END
|
G_STMT_END
|
||||||
#elif defined(__NR_futex_time64)
|
#endif /* defined(__BIONIC__) */
|
||||||
|
#elif defined(HAVE_FUTEX_TIME64)
|
||||||
#define g_futex_simple(uaddr, futex_op, ...) \
|
#define g_futex_simple(uaddr, futex_op, ...) \
|
||||||
G_STMT_START \
|
G_STMT_START \
|
||||||
{ \
|
{ \
|
||||||
@ -96,7 +128,7 @@ struct _GRealThread
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
G_STMT_END
|
G_STMT_END
|
||||||
#elif defined(__NR_futex)
|
#elif defined(HAVE_FUTEX)
|
||||||
#define g_futex_simple(uaddr, futex_op, ...) \
|
#define g_futex_simple(uaddr, futex_op, ...) \
|
||||||
G_STMT_START \
|
G_STMT_START \
|
||||||
{ \
|
{ \
|
||||||
@ -108,9 +140,9 @@ struct _GRealThread
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
G_STMT_END
|
G_STMT_END
|
||||||
#else /* !defined(__NR_futex) && !defined(__NR_futex_time64) */
|
#else /* !defined(HAVE_FUTEX) && !defined(HAVE_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 /* defined(HAVE_FUTEX) && defined(HAVE_FUTEX_TIME64) */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -994,7 +994,7 @@ if cc.compiles('''#include <linux/futex.h>
|
|||||||
int main (int argc, char ** argv) {
|
int main (int argc, char ** argv) {
|
||||||
syscall (__NR_futex_time64, NULL, FUTEX_WAKE, FUTEX_WAIT);
|
syscall (__NR_futex_time64, NULL, FUTEX_WAKE, FUTEX_WAIT);
|
||||||
return 0;
|
return 0;
|
||||||
}''', name : 'futex(2) system call')
|
}''', name : 'futex_time64(2) system call')
|
||||||
glib_conf.set('HAVE_FUTEX_TIME64', 1)
|
glib_conf.set('HAVE_FUTEX_TIME64', 1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user