[Python-checkins] bpo-47260: Fix os.closerange() potentially being a no-op in a seccomp sandbox (GH-32418)

miss-islington webhook-mailer at python.org
Fri Apr 8 14:10:43 EDT 2022


https://github.com/python/cpython/commit/89697f7374ea947ebe8e36131e2d3e21fff6fa1d
commit: 89697f7374ea947ebe8e36131e2d3e21fff6fa1d
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-04-08T11:10:38-07:00
summary:

bpo-47260: Fix os.closerange() potentially being a no-op in a seccomp sandbox (GH-32418)


_Py_closerange() currently assumes that close_range() closes
all file descriptors even if it returns an error (other than ENOSYS).
This assumption can be wrong on Linux if a seccomp sandbox denies
the underlying syscall, pretending that it returns EPERM or EACCES.
In this case _Py_closerange() won't close any descriptors at all,
which in the worst case can be a security issue.

Fix this by falling back to other methods in case of any close_range()
error. Note that fallbacks will not be triggered on any problems with
closing individual file descriptors because close_range() is documented
to ignore such errors on both Linux[1] and FreeBSD[2].

[1] https://man7.org/linux/man-pages/man2/close_range.2.html
[2] https://www.freebsd.org/cgi/man.cgi?query=close_range&sektion=2
(cherry picked from commit 1c8b3b5d66a629258f1db16939b996264a8b9c37)

Co-authored-by: Alexey Izbyshev <izbyshev at ispras.ru>

files:
A Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst
M Python/fileutils.c

diff --git a/Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst b/Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst
new file mode 100644
index 0000000000000..300baa19c279a
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-04-08-14-30-53.bpo-47260.TtcNxI.rst
@@ -0,0 +1,2 @@
+Fix ``os.closerange()`` potentially being a no-op in a Linux seccomp
+sandbox.
diff --git a/Python/fileutils.c b/Python/fileutils.c
index c3144ee40782e..3b53baa00eeb1 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -2395,10 +2395,11 @@ _Py_closerange(int first, int last)
     first = Py_MAX(first, 0);
     _Py_BEGIN_SUPPRESS_IPH
 #ifdef HAVE_CLOSE_RANGE
-    if (close_range(first, last, 0) == 0 || errno != ENOSYS) {
-        /* Any errors encountered while closing file descriptors are ignored;
-         * ENOSYS means no kernel support, though,
-         * so we'll fallback to the other methods. */
+    if (close_range(first, last, 0) == 0) {
+        /* close_range() ignores errors when it closes file descriptors.
+         * Possible reasons of an error return are lack of kernel support
+         * or denial of the underlying syscall by a seccomp sandbox on Linux.
+         * Fallback to other methods in case of any error. */
     }
     else
 #endif /* HAVE_CLOSE_RANGE */



More information about the Python-checkins mailing list