Blob Blame History Raw
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