Add --bind-fd and --ro-bind-fd to let you bind a O_PATH fd for flatpak fix CVE-2024-42472
(cherry picked from commit 622d88b99580cd021717f1237cc2ecc7647c1cc6)
This commit is contained in:
parent
a38eac1f08
commit
2c09c78acd
@ -0,0 +1,115 @@
|
|||||||
|
From a253257cd298892da43e15201d83f9a02c9b58b5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexander Larsson <alexl@redhat.com>
|
||||||
|
Date: Tue, 18 Jun 2024 10:20:36 +0200
|
||||||
|
Subject: [PATCH] Add --bind-fd and --ro-bind-fd to let you bind a O_PATH fd.
|
||||||
|
|
||||||
|
Origin: https://github.com/containers/bubblewrap/commit/a253257cd298892da43e15201d83f9a02c9b58b5
|
||||||
|
|
||||||
|
This is useful for example if you for some reason don't have the real
|
||||||
|
path. It is also a way to make bind-mounts race-free (i.e. to have the
|
||||||
|
mount actually be the thing you wanted to be mounted, avoiding issues
|
||||||
|
where some other process replaces the target in parallel with the bwrap
|
||||||
|
launch.
|
||||||
|
|
||||||
|
Unfortunately due to some technical details we can't actually directly
|
||||||
|
mount the dirfd, as they come from different user namespace which is not
|
||||||
|
permitted, but at least we can delay resolving the fd to a path as much as
|
||||||
|
possible, and then validate after mount that we actually mounted the right
|
||||||
|
thing.
|
||||||
|
|
||||||
|
Signed-off-by: Alexander Larsson <alexl@redhat.com>
|
||||||
|
---
|
||||||
|
bubblewrap.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
tests/test-run.sh | 6 ++++++
|
||||||
|
2 files changed, 56 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/bubblewrap.c b/bubblewrap.c
|
||||||
|
index c414bb06..bc75da47 100644
|
||||||
|
--- a/bubblewrap.c
|
||||||
|
+++ b/bubblewrap.c
|
||||||
|
@@ -341,6 +341,8 @@ usage (int ecode, FILE *out)
|
||||||
|
" --dev-bind-try SRC DEST Equal to --dev-bind but ignores non-existent SRC\n"
|
||||||
|
" --ro-bind SRC DEST Bind mount the host path SRC readonly on DEST\n"
|
||||||
|
" --ro-bind-try SRC DEST Equal to --ro-bind but ignores non-existent SRC\n"
|
||||||
|
+ " --bind-fd FD DEST Bind open directory or path fd on DEST\n"
|
||||||
|
+ " --ro-bind-fd FD DEST Bind open directory or path fd read-only on DEST\n"
|
||||||
|
" --remount-ro DEST Remount DEST as readonly; does not recursively remount\n"
|
||||||
|
" --exec-label LABEL Exec label for the sandbox\n"
|
||||||
|
" --file-label LABEL File label for temporary sandbox content\n"
|
||||||
|
@@ -1231,6 +1233,30 @@ setup_newroot (bool unshare_pid,
|
||||||
|
(op->type == SETUP_RO_BIND_MOUNT ? BIND_READONLY : 0) |
|
||||||
|
(op->type == SETUP_DEV_BIND_MOUNT ? BIND_DEVICES : 0),
|
||||||
|
0, 0, source, dest);
|
||||||
|
+
|
||||||
|
+ if (op->fd >= 0)
|
||||||
|
+ {
|
||||||
|
+ struct stat fd_st, mount_st;
|
||||||
|
+
|
||||||
|
+ /* When using bind-fd, there is a race condition between resolving the fd as a magic symlink
|
||||||
|
+ * and mounting it, where someone could replace what is at the symlink target. Ideally
|
||||||
|
+ * we would not even resolve the symlink and directly bind-mount from the fd, but unfortunately
|
||||||
|
+ * we can't do that, because its not permitted to bind mount a fd from another user namespace.
|
||||||
|
+ * So, we resolve, mount and then compare fstat+stat to detect the race. */
|
||||||
|
+
|
||||||
|
+ if (fstat(op->fd, &fd_st) != 0)
|
||||||
|
+ die_with_error("Can't stat fd %d", op->fd);
|
||||||
|
+ if (lstat(dest, &mount_st) != 0)
|
||||||
|
+ die_with_error("Can't stat mount at %s", dest);
|
||||||
|
+
|
||||||
|
+ if (fd_st.st_ino != mount_st.st_ino ||
|
||||||
|
+ fd_st.st_dev != mount_st.st_dev)
|
||||||
|
+ die_with_error("Race condition binding dirfd");
|
||||||
|
+
|
||||||
|
+ close(op->fd);
|
||||||
|
+ op->fd = -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SETUP_REMOUNT_RO_NO_RECURSIVE:
|
||||||
|
@@ -1874,6 +1900,30 @@ parse_args_recurse (int *argcp,
|
||||||
|
if (strcmp(arg, "--dev-bind-try") == 0)
|
||||||
|
op->flags = ALLOW_NOTEXIST;
|
||||||
|
|
||||||
|
+ argv += 2;
|
||||||
|
+ argc -= 2;
|
||||||
|
+ }
|
||||||
|
+ else if (strcmp (arg, "--bind-fd") == 0 ||
|
||||||
|
+ strcmp (arg, "--ro-bind-fd") == 0)
|
||||||
|
+ {
|
||||||
|
+ int src_fd;
|
||||||
|
+ char *endptr;
|
||||||
|
+
|
||||||
|
+ if (argc < 3)
|
||||||
|
+ die ("--bind-fd takes two arguments");
|
||||||
|
+
|
||||||
|
+ src_fd = strtol (argv[1], &endptr, 10);
|
||||||
|
+ if (argv[1][0] == 0 || endptr[0] != 0 || src_fd < 0)
|
||||||
|
+ die ("Invalid fd: %s", argv[1]);
|
||||||
|
+
|
||||||
|
+ if (strcmp(arg, "--ro-bind-fd") == 0)
|
||||||
|
+ op = setup_op_new (SETUP_RO_BIND_MOUNT);
|
||||||
|
+ else
|
||||||
|
+ op = setup_op_new (SETUP_BIND_MOUNT);
|
||||||
|
+ op->source = xasprintf ("/proc/self/fd/%d", src_fd);
|
||||||
|
+ op->fd = src_fd;
|
||||||
|
+ op->dest = argv[2];
|
||||||
|
+
|
||||||
|
argv += 2;
|
||||||
|
argc -= 2;
|
||||||
|
}
|
||||||
|
diff --git a/tests/test-run.sh b/tests/test-run.sh
|
||||||
|
index 6151f1a8..8d063b57 100755
|
||||||
|
--- a/tests/test-run.sh
|
||||||
|
+++ b/tests/test-run.sh
|
||||||
|
@@ -565,4 +565,10 @@ $RUN --argv0 right sh -c 'echo $0' > stdout
|
||||||
|
assert_files_equal stdout reference
|
||||||
|
echo "ok - environment manipulation"
|
||||||
|
|
||||||
|
+echo "foobar" > file-data
|
||||||
|
+$RUN --proc /proc --dev /dev --bind / / --bind-fd 100 /tmp cat /tmp/file-data 100< . > stdout
|
||||||
|
+assert_file_has_content stdout foobar
|
||||||
|
+
|
||||||
|
+echo "ok - bind-fd"
|
||||||
|
+
|
||||||
|
echo "ok - End of test"
|
||||||
@ -1,10 +1,11 @@
|
|||||||
Name: bubblewrap
|
Name: bubblewrap
|
||||||
Version: 0.8.0
|
Version: 0.8.0
|
||||||
Release: 1
|
Release: 2
|
||||||
Summary: Core execution tool for unprivileged containers
|
Summary: Core execution tool for unprivileged containers
|
||||||
License: LGPLv2+
|
License: LGPLv2+
|
||||||
URL: https://github.com/projectatomic/bubblewrap
|
URL: https://github.com/projectatomic/bubblewrap
|
||||||
Source0: https://github.com/containers/bubblewrap/releases/download/v%{version}/bubblewrap-%{version}.tar.xz
|
Source0: https://github.com/containers/bubblewrap/releases/download/v%{version}/bubblewrap-%{version}.tar.xz
|
||||||
|
Patch0: backport-Add--bind-fd-and--ro-bind-fd-to-let-you-bind-a-O_PATH-fd.patch
|
||||||
|
|
||||||
BuildRequires: autoconf automake libtool gcc libcap-devel
|
BuildRequires: autoconf automake libtool gcc libcap-devel
|
||||||
BuildRequires: pkgconfig(libselinux) libxslt docbook-style-xsl
|
BuildRequires: pkgconfig(libselinux) libxslt docbook-style-xsl
|
||||||
@ -40,6 +41,9 @@ if ! test -x configure; then NOCONFIGURE=1 ./autogen.sh; fi
|
|||||||
%{_mandir}/man1/*
|
%{_mandir}/man1/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Aug 16 2024 wangkai <13474090681@163.com> - 0.8.0-2
|
||||||
|
- Add --bind-fd and --ro-bind-fd to let you bind a O_PATH fd for flatpak fix CVE-2024-42472
|
||||||
|
|
||||||
* Wed Nov 22 2023 konglidong <konglidong@uniontech.com> - 0.8.0-1
|
* Wed Nov 22 2023 konglidong <konglidong@uniontech.com> - 0.8.0-1
|
||||||
- Update version to 0.8.0
|
- Update version to 0.8.0
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user