From 24de599887f641271ea279a0421776990075b714 Mon Sep 17 00:00:00 2001
From: David King <amigadave@amigadave.com>
Date: Tue, 12 Mar 2024 10:15:03 +0000
Subject: [PATCH] gspawn: Additionally handle EPERM
Handle old broken versions of Docker and libseccomp which do not
recognise close_range().
https://github.com/opencontainers/runc/issues/2151
https://salsa.debian.org/debian/libseccomp/-/blob/debian/bullseye/debian/patches/syscalls_add_close_range_syscall.patch
Based on a patch by Richard Hughes.
---
glib/glib-unix.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/glib/glib-unix.c b/glib/glib-unix.c
index 7cb76dd33..9b2dfe2d9 100644
--- a/glib/glib-unix.c
+++ b/glib/glib-unix.c
@@ -835,9 +835,18 @@ g_fdwalk_set_cloexec (int lowfd)
*
* Handle ENOSYS in case it’s supported in libc but not the kernel; if so,
* fall back to safe_fdwalk(). Handle EINVAL in case `CLOSE_RANGE_CLOEXEC`
- * is not supported. */
+ * is not supported.
+ *
+ * Also handle EPERM for the cases where GLi is running under broken versions
+ * of Docker+libseccomp which don't recognise `close_range()` so block calls
+ * to it under a default security policy which returns EPERM rather than (the
+ * correct) ENOSYS. This workaround should be carried in distributions until
+ * they have versions of libseccomp and Docker which contain:
+ * - https://salsa.debian.org/debian/libseccomp/-/blob/debian/bullseye/debian/patches/syscalls_add_close_range_syscall.patch
+ * - https://github.com/opencontainers/runc/issues/2151
+ */
ret = close_range (lowfd, G_MAXUINT, CLOSE_RANGE_CLOEXEC);
- if (ret == 0 || !(errno == ENOSYS || errno == EINVAL))
+ if (ret == 0 || !(errno == ENOSYS || errno == EINVAL || errno == EPERM))
return ret;
#endif /* HAVE_CLOSE_RANGE */
@@ -882,9 +891,15 @@ g_closefrom (int lowfd)
* situations: https://bugs.python.org/issue38061
*
* Handle ENOSYS in case it’s supported in libc but not the kernel; if so,
- * fall back to safe_fdwalk(). */
+ * fall back to safe_fdwalk().
+ *
+ * Also handle EPERM for the cases where GLib is running under broken versions
+ * of Docker+libseccomp which don’t recognise `close_range()` so block calls
+ * to it under a default security policy which returns EPERM rather than (the
+ * correct) ENOSYS.
+ */
ret = close_range (lowfd, G_MAXUINT, 0);
- if (ret == 0 || errno != ENOSYS)
+ if (ret == 0 || !(errno == ENOSYS || errno == EPERM))
return ret;
#endif /* HAVE_CLOSE_RANGE */
--
2.44.0