diff options
author | L. E. Segovia <amy@centricular.com> | 2024-03-28 18:42:06 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2024-04-03 10:27:26 +0100 |
commit | 4e7f965294277ca90c97741de5e536cf6f16349b (patch) | |
tree | 329a0f3982441d606dda199578a30a3c585da026 | |
parent | 49dd29cc920438e34ad151c09c18b72a41f97a50 (diff) |
glib: Block futex_time64 usage on Android API level < 30
This syscall is seccomp blocked on all lower API levels:
https://github.com/aosp-mirror/platform_bionic/commit/ee7bc3002dc3127faac110167d28912eb0e86a20
Part-of: <https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/1441>
5 files changed, 278 insertions, 0 deletions
diff --git a/recipes/glib.recipe b/recipes/glib.recipe index 1d4347c0..ec609ae4 100644 --- a/recipes/glib.recipe +++ b/recipes/glib.recipe @@ -49,6 +49,12 @@ class Recipe(recipe.Recipe): 'glib/0001-gthread-posix-need-to-include-errno.h.patch', # Upstreamed since 2.75 (remove when bumping version) 'glib/0001-giomodule-Automatically-detect-modules-on-macOS.patch', + # futex_time64 is seccomp blocked in Android API level < 30 + # Upstreamed since 2.81 (remove when bumping version) + f'{name}/0009-glib-gthread-posix-Block-futex_time64-usage-on-Andro.patch', + f'{name}/0010-glib-gthread-posix-Fix-name-of-the-futex_time64-2-te.patch', + f'{name}/0011-glib-gthread-posix-Use-the-config.h-macros-to-detect.patch', + f'{name}/0012-glib-gthread-posix-Fix-missing-saved_errno-variable-.patch' ] files_libs = [ diff --git a/recipes/glib/0009-glib-gthread-posix-Block-futex_time64-usage-on-Andro.patch b/recipes/glib/0009-glib-gthread-posix-Block-futex_time64-usage-on-Andro.patch new file mode 100644 index 00000000..a4025e47 --- /dev/null +++ b/recipes/glib/0009-glib-gthread-posix-Block-futex_time64-usage-on-Andro.patch @@ -0,0 +1,120 @@ +From 7482aae98e9013328858c40e8de6e4c4a0ecc7f0 Mon Sep 17 00:00:00 2001 +From: "L. E. Segovia" <amy@centricular.com> +Date: Mon, 1 Apr 2024 23:55:01 -0300 +Subject: [PATCH 09/12] glib/gthread-posix: Block futex_time64 usage on Android + API level < 30 + +This syscall is seccomp blocked on all lower API levels: + +https://github.com/aosp-mirror/platform_bionic/commit/ee7bc3002dc3127faac110167d28912eb0e86a20 +(cherry picked from commit 06ea9aed58c6372b4138d3668ef0f93465ab70d0) +--- + glib/gthread-posix.c | 20 +++++++++++++++----- + glib/gthreadprivate.h | 34 +++++++++++++++++++++++++++++++++- + 2 files changed, 48 insertions(+), 6 deletions(-) + +diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c +index 84f62881d..cafbc9d54 100644 +--- a/glib/gthread-posix.c ++++ b/glib/gthread-posix.c +@@ -1634,11 +1634,17 @@ 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` +- * syscall with the `struct timespec` used by the kernel, which uses +- * `__kernel_long_t` for both its fields. We use that instead of +- * `__kernel_old_time_t` because it is equivalent and available in the +- * kernel headers for a longer time. ++ * 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. ++ * 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 + * define `__NR_futex_time64`. +@@ -1648,7 +1654,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; +diff --git a/glib/gthreadprivate.h b/glib/gthreadprivate.h +index 6eaf42275..94a77fd33 100644 +--- a/glib/gthreadprivate.h ++++ b/glib/gthreadprivate.h +@@ -57,10 +57,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 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 + * 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 \ + { \ +@@ -69,6 +100,7 @@ struct _GRealThread + syscall (__NR_futex, uaddr, (gsize) futex_op, __VA_ARGS__); \ + } \ + G_STMT_END ++#endif /* defined(__BIONIC__) */ + #elif defined(__NR_futex_time64) + #define g_futex_simple(uaddr, futex_op, ...) \ + G_STMT_START \ +@@ -84,7 +116,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 +-- +2.44.0.windows.1 + diff --git a/recipes/glib/0010-glib-gthread-posix-Fix-name-of-the-futex_time64-2-te.patch b/recipes/glib/0010-glib-gthread-posix-Fix-name-of-the-futex_time64-2-te.patch new file mode 100644 index 00000000..1581d215 --- /dev/null +++ b/recipes/glib/0010-glib-gthread-posix-Fix-name-of-the-futex_time64-2-te.patch @@ -0,0 +1,27 @@ +From dad2144e61075ca6ae8b52a53aa52946fc273f53 Mon Sep 17 00:00:00 2001 +From: "L. E. Segovia" <amy@centricular.com> +Date: Mon, 1 Apr 2024 23:55:39 -0300 +Subject: [PATCH 10/12] glib/gthread-posix: Fix name of the futex_time64(2) + test in the Meson log + +(cherry picked from commit ffa639f0b7aae99cffd657bf306358dd623ca9d0) +--- + meson.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index be468c3f3..4c2c150a7 100644 +--- a/meson.build ++++ b/meson.build +@@ -900,7 +900,7 @@ if cc.compiles('''#include <linux/futex.h> + int main (int argc, char ** argv) { + syscall (__NR_futex_time64, NULL, FUTEX_WAKE, FUTEX_WAIT); + return 0; +- }''', name : 'futex(2) system call') ++ }''', name : 'futex_time64(2) system call') + glib_conf.set('HAVE_FUTEX_TIME64', 1) + endif + +-- +2.44.0.windows.1 + diff --git a/recipes/glib/0011-glib-gthread-posix-Use-the-config.h-macros-to-detect.patch b/recipes/glib/0011-glib-gthread-posix-Use-the-config.h-macros-to-detect.patch new file mode 100644 index 00000000..24c5850c --- /dev/null +++ b/recipes/glib/0011-glib-gthread-posix-Use-the-config.h-macros-to-detect.patch @@ -0,0 +1,99 @@ +From 80d8f886ee86963defd816f4aae5c4df697dee14 Mon Sep 17 00:00:00 2001 +From: "L. E. Segovia" <amy@centricular.com> +Date: Mon, 1 Apr 2024 23:57:46 -0300 +Subject: [PATCH 11/12] glib/gthread-posix: Use the config.h macros to detect + futex support + +(cherry picked from commit 049c8e70c8f759d36bcf70f773e2e748f0f77738) +--- + glib/gthread-posix.c | 10 +++++----- + glib/gthreadprivate.h | 10 +++++----- + 2 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c +index cafbc9d54..08a8acf6a 100644 +--- a/glib/gthread-posix.c ++++ b/glib/gthread-posix.c +@@ -1653,7 +1653,7 @@ g_cond_wait_until (GCond *cond, + sampled = cond->i[0]; + g_mutex_unlock (mutex); + +-#ifdef __NR_futex_time64 ++#if defined(HAVE_FUTEX_TIME64) + #if defined(__BIONIC__) + if (__builtin_available (android 30, *)) { + #else +@@ -1674,9 +1674,9 @@ g_cond_wait_until (GCond *cond, + * normal `futex` syscall. This can happen if newer kernel headers are + * used than the kernel that is actually running. + */ +-# ifdef __NR_futex ++# if defined(HAVE_FUTEX) + if (res >= 0 || errno != ENOSYS) +-# endif /* defined(__NR_futex) */ ++# endif /* defined(HAVE_FUTEX) */ + { + success = (res < 0 && errno == ETIMEDOUT) ? FALSE : TRUE; + g_mutex_lock (mutex); +@@ -1686,7 +1686,7 @@ g_cond_wait_until (GCond *cond, + } + #endif + +-#ifdef __NR_futex ++#if defined(HAVE_FUTEX) + { + struct + { +@@ -1707,7 +1707,7 @@ g_cond_wait_until (GCond *cond, + + return success; + } +-#endif /* defined(__NR_futex) */ ++#endif /* defined(HAVE_FUTEX) */ + + /* We can't end up here because of the checks above */ + g_assert_not_reached (); +diff --git a/glib/gthreadprivate.h b/glib/gthreadprivate.h +index 94a77fd33..a3a89e72e 100644 +--- a/glib/gthreadprivate.h ++++ b/glib/gthreadprivate.h +@@ -66,7 +66,7 @@ struct _GRealThread + * 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(HAVE_FUTEX) && defined(HAVE_FUTEX_TIME64) + #if defined(__BIONIC__) + #define g_futex_simple(uaddr, futex_op, ...) \ + G_STMT_START \ +@@ -101,23 +101,23 @@ struct _GRealThread + } \ + G_STMT_END + #endif /* defined(__BIONIC__) */ +-#elif defined(__NR_futex_time64) ++#elif defined(HAVE_FUTEX_TIME64) + #define g_futex_simple(uaddr, futex_op, ...) \ + G_STMT_START \ + { \ + syscall (__NR_futex_time64, uaddr, (gsize) futex_op, __VA_ARGS__); \ + } \ + G_STMT_END +-#elif defined(__NR_futex) ++#elif defined(HAVE_FUTEX) + #define g_futex_simple(uaddr, futex_op, ...) \ + G_STMT_START \ + { \ + syscall (__NR_futex, uaddr, (gsize) futex_op, __VA_ARGS__); \ + } \ + 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 available" +-#endif /* defined(__NR_futex) && defined(__NR_futex_time64) */ ++#endif /* defined(HAVE_FUTEX) && defined(HAVE_FUTEX_TIME64) */ + + #endif + +-- +2.44.0.windows.1 + diff --git a/recipes/glib/0012-glib-gthread-posix-Fix-missing-saved_errno-variable-.patch b/recipes/glib/0012-glib-gthread-posix-Fix-missing-saved_errno-variable-.patch new file mode 100644 index 00000000..519389dc --- /dev/null +++ b/recipes/glib/0012-glib-gthread-posix-Fix-missing-saved_errno-variable-.patch @@ -0,0 +1,26 @@ +From b03f60ff07ff610bbbdcd2e8df12dc0b45d55434 Mon Sep 17 00:00:00 2001 +From: "L. E. Segovia" <amy@centricular.com> +Date: Tue, 2 Apr 2024 18:45:23 -0300 +Subject: [PATCH 12/12] glib/gthread-posix: Fix missing saved_errno variable in + Android's g_futex_simple + +(cherry picked from commit bfebf55d18647092d3a2e83cbda5d6967f8e2a68) +--- + glib/gthreadprivate.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/glib/gthreadprivate.h b/glib/gthreadprivate.h +index a3a89e72e..9d858f6a3 100644 +--- a/glib/gthreadprivate.h ++++ b/glib/gthreadprivate.h +@@ -71,6 +71,7 @@ struct _GRealThread + #define g_futex_simple(uaddr, futex_op, ...) \ + G_STMT_START \ + { \ ++ int saved_errno = errno; \ + int res = 0; \ + if (__builtin_available (android 30, *)) \ + { \ +-- +2.44.0.windows.1 + |