Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flatpak-1.6.x] Backport CVE-2021-21261, CVE-2021-21381 and CVE-2021-41133 fixes #4537

Open
wants to merge 37 commits into
base: flatpak-1.6.x
Choose a base branch
from

Conversation

debarshiray
Copy link
Contributor

@debarshiray debarshiray commented Nov 2, 2021

We are carrying these in RHEL 8.2. Given that these are security fixes, I thought that I might as well put them on the upstream flatpak-1.6.x branch, and let everybody benefit.

(We do backport fixes for CVEs rated as important to older RHEL point-releases.)

Based on #4456


  • Fix build with GCC 11
    (cherry picked from commit ff0ca9a)

  • CI: Do one build out-of-tree
    (cherry picked from commit 0d58999)

  • tests: Add and use "ok" helper
    (cherry picked from commit b1fdf6c)

  • Add --enable-asan option
    (cherry picked from commit 0a16938)

  • CI: Use the new --enable-asan
    (cherry picked from commit be70cd5)

  • CI: Add mono apt repo to fix build
    (cherry picked from commit c647062)

  • Drop old-glib ci test as ubuntu 16.04 is no longer available
    (backported from commit 481e5c8)

  • common: Add a backport of G_DBUS_METHOD_INVOCATION_HANDLED
    (cherry picked from commit d1d05a7)

  • system-helper: Return G_DBUS_METHOD_INVOCATION_HANDLED where appropriate
    (cherry picked from commit fb6f1ea)

  • system-helper: Fix deploys of local remotes
    (cherry picked from commit 16290b5)

  • tests: Work around summary mtime cache issue (for 1.6 branch)
    (cherry picked from commit 07e6a2c)

  • run: Convert all environment variables into bwrap arguments
    (cherry picked from commit dcd2494)

  • tests: Expand coverage for environment variable overrides
    (cherry picked from commit 6a11007)

  • context: Add --env-fd option
    (cherry picked from commit 57416f3)

  • portal: Convert --env in extra-args into --env-fd
    (backported from commit fb1eaef)

  • tests: Exercise --env-fd
    (cherry picked from commit 7bb78f8)

  • portal: Do not use caller-supplied variables in environment
    (cherry picked from commit 26f09bf)

  • tests: Assert that --env= does not go in flatpak run or bwrap environ
    (cherry picked from commit 5019b30)

  • Fix tests when installed tests are not enabled
    (cherry picked from commit e3d06dd)

  • build: Convert environment into a sequence of bwrap arguments
    (cherry picked from commit 93ecea3)

  • dir: Pass environment via bwrap --setenv when running apply_extra
    (cherry picked from commit f91857c)

  • Disallow @@ and @@U usage in desktop files
    (cherry picked from commit c54e7c3)

  • dir: Reserve the whole @@ prefix
    (cherry picked from commit cc7526b)

  • dir: Refuse to export .desktop files with suspicious uses of @@ tokens
    (cherry picked from commit 754450e)

  • tree-wide: Replace usages of whitelist/blacklist
    (cherry picked from commit a994cdb)

  • Fix argument order of clone() for s390x in seccomp filter
    (cherry picked from commit f4c3ea5)

  • run: Add an errno value to seccomp filters
    (cherry picked from commit 89f9bb7)

  • run: Add cross-references for some other seccomp syscall filters
    (cherry picked from commit 13d34f9)

  • common: Add a list of recently-added Linux syscalls
    (cherry picked from commit cf9cdd9)

  • run: Block clone3() in sandbox
    (cherry picked from commit 08c65cd)

  • run: Disallow recently-added mount-manipulation syscalls
    (cherry picked from commit db4ccf7)

  • run: Block setns()
    (cherry picked from commit a01fc5f)

  • run: Don't allow unmounting filesystems
    (cherry picked from commit 758b8ca)

  • run: Don't allow chroot()
    (cherry picked from commit 8f87696)

  • run: Handle unknown syscalls as intended
    (cherry picked from commit a0055e4)

  • Fix handling of syscalls only allowed by --devel
    (cherry picked from commit da503e0)

  • run: Improve error handling/diagnostics for calls into libseccomp
    (cherry picked from commit adaa025)

@debarshiray debarshiray force-pushed the wip/rishi/CVE-2021-21261-CVE-2021-21381-CVE-2021-41133-1.6 branch 5 times, most recently from 975ecc1 to e3a116c Compare November 3, 2021 00:54
@smcv
Copy link
Collaborator

smcv commented Nov 3, 2021

You'll probably also want to backport the equivalent of #4474, to fix the things that regressed when we fixed CVE-2021-21261.

(I'd also appreciate testing and review of #4474.)

@smcv
Copy link
Collaborator

smcv commented Nov 3, 2021

What libseccomp do you have in RHEL 8.2? If you want to block clone3() for CVE-2021-41133, you'll need at least 2.5.0, or some backported patches.

@debarshiray
Copy link
Contributor Author

What libseccomp do you have in RHEL 8.2? If you want to
block clone3() for CVE-2021-41133, you'll need at least 2.5.0,
or some backported patches.

RHEL 8.2 only has 2.4.1. As far as I can make out, these flatpak-1.6.x backports do work - both in my quick smoke testing and in the hands of the QE team. Am I missing something?

@debarshiray
Copy link
Contributor Author

You'll probably also want to backport the equivalent of #4474,
to fix the things that regressed when we fixed CVE-2021-21261.

I am a bit torn.

The build fix with GCC 11 definitely seems safe enough to use. However, for the rest, I can only do some superficial smoke testing. I wouldn't be able to get the RHEL QE team to give them any sort of rigorous scrutiny.

I am somewhat confident about the patches that are currently in this PR because they went through QE and are currently shipping.

What do you think?

(I'd also appreciate testing and review of #4474.)

I can certainly help with that. :)

@smcv
Copy link
Collaborator

smcv commented Nov 3, 2021

RHEL 8.2 only has 2.4.1. As far as I can make out, these flatpak-1.6.x backports do work - both in my quick smoke testing and in the hands of the QE team. Am I missing something?

If your kernel knows about clone3() but your libseccomp does not, then Flatpak will not be able to prevent clone3() from being called by apps that have the "multiarch" feature enabled (those that need to be able to run i386 code on x86_64, like Steam), or by extra-data extractors.

@smcv
Copy link
Collaborator

smcv commented Nov 6, 2021

You'll probably also want to backport the equivalent of #4474,
to fix the things that regressed when we fixed CVE-2021-21261.

The build fix with GCC 11 definitely seems safe enough to use. However, for the rest, I can only do some superficial smoke testing. I wouldn't be able to get the RHEL QE team to give them any sort of rigorous scrutiny.

To be clear, I'm not saying that backporting the equivalent of #4474 is a blocker for merging this. However, if we don't have the equivalent of #4474, then there will be known, unfixed regressions in the flatpak-1.6.x branch. Is that OK or not? I honestly don't know - if you're pushing to 1.6.x mainly for the benefit of Red Hat and Canonical, then it's really up to Red Hat and Canonical what their policies look like.

The only distribution whose security policies I'm familiar with is Debian, and if a security fix causes regressions, the Debian security team does try to release fixes for those regressions as a revised DSA (example), to avoid creating an incentive for users to not apply security updates.

I don't have access to a QA team, so you're already ahead of the amount of testing I can do - my Flatpak contributions are as an individual, with occasional help from one of my Collabora colleagues if the contribution is work-related. Of course in an ideal world I wouldn't have committed a security fix that caused regressions, but it's not always feasible to avoid mistakes, particularly when working under embargo with only a small number of possible reviewers. CVE-2021-21261 is something I noticed while doing feature development (I wasn't specifically looking for vulnerabilities), and I only found the regression when I went back to working on the new feature.

mcatanzaro and others added 8 commits January 27, 2022 00:40
With the gcc build out-of-tree and the clang build in-tree, we're
testing both ways.

Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 0d58999)
This allows us to print some separators for the logs also.

tests: Convert more tests to ok helper
(cherry picked from commit b1fdf6c)
This passes -fsanitize=address in the right place.
Passing it this way instead of CFLAGS allows us to strategically
not add sanitize in specific places as needed.

(cherry picked from commit 97a153f)
(cherry picked from commit 0a16938)
(cherry picked from commit d5de05b)
(cherry picked from commit be70cd5)
For whatever reason parts of mono is installed, but the repo is not
configured so there is a version conflict on update:

libglib2.0-cil is already the newest version (2.12.45-0xamarin19+ubuntu1604b1).
libglib2.0-cil set to manually installed.
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 libglib2.0-cil-dev : Depends: libglib2.0-cil (= 2.12.10-6) but 2.12.45-0xamarin19+ubuntu1604b1 is to be installed
E: Unable to correct problems, you have held broken packages.

(cherry picked from commit b6d5e20)
(cherry picked from commit c647062)
As per actions/runner-images#3287
the support for ubuntu-16.04 stopped working on september 20:th, so
our CI job stopped starting.

(This matches what we did on master)

(backported from commit 481e5c8)
This is syntactic sugar added in GLib 2.67.0, which makes it more clearly
correct when we return TRUE after a GDBus error.

Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit cc7f863)
(cherry picked from commit d1d05a7)
@debarshiray debarshiray force-pushed the wip/rishi/CVE-2021-21261-CVE-2021-21381-CVE-2021-41133-1.6 branch from e3a116c to 5d30f3e Compare January 26, 2022 23:42
@debarshiray
Copy link
Contributor Author

You'll probably also want to backport the equivalent of #4474,
to fix the things that regressed when we fixed CVE-2021-21261.

The build fix with GCC 11 definitely seems safe enough to use.

I have now included the build fix with GCC 11 in this pull request, since I need it to build the code on my Fedora 35 laptop which vastly simplifies my life. :)

However, for the rest, I can only do some superficial smoke testing.
I wouldn't be able to get the RHEL QE team to give them any sort of
rigorous scrutiny.

To be clear, I'm not saying that backporting the equivalent of #4474 is a
blocker for merging this. However, if we don't have the equivalent of #4474,
then there will be known, unfixed regressions in the flatpak-1.6.x branch.
Is that OK or not? I honestly don't know - if you're pushing to 1.6.x mainly
for the benefit of Red Hat and Canonical, then it's really up to Red Hat and
Canonical what their policies look like.

Red Hat's security team had flagged CVE-2021-21261, CVE-2021-21381 and CVE-2021-41133 as important. This meant that they had to be fixed in older RHEL point releases. eg., CVE-2021-21261 came out during the RHEL 8.4 development cycle, but it was still fixed for RHELs 8.2, 8.1 and 7.9.

For such fixes to older RHEL point releases, the patches need to be strictly targeted fixes. There's no way for me to include the regression fixes that happened later (such as the ones in #4474) unless I can convince various people that they are critical enough to roll out another series of updates going all the way back to 7.9. I suspect that I will be encouraged to let sleeping dogs lie. :)

However, it's a lot easier for me to pull in fixes from the upstream stable branches for future RHEL point releases. eg., the flatpak-1.8.6 release for RHEL 8.6.

My motivation behind this pull request is to simply publish all the backports for flatpak-1.6.x that we are already carrying downstream in a sane way. They went through the usual scrutiny from the RHEL QE team and are part of the public RHEL SRPMs anyway. If nothing else, having them as part of the upstream Git branch will make my life a lot saner when I have to do another round of backports for the next important CVE.

I won't be pushing for new releases from the flatpak-1.6.x branch, because I can't use them anywhere. However, if Ubuntu wants to include a new tarball in 20.04 LTS, then I'd be happy to see them use these backports.

So, in short, I am reluctant to backport more fixes at the moment because I can't ship them anywhere and can't thoroughly test them.

The only distribution whose security policies I'm familiar with is Debian, and
if a security fix causes regressions, the Debian security team does try to
release fixes for those regressions as a revised DSA
(example),
to avoid creating an incentive for users to not apply security updates.

I will try to find out what RHEL's policy is about regressions in security updates. All this happened while the Flatpak stack was owned by @alexlarsson and @amigadave in Fedora and RHEL, so I might be missing some context.

Of course in an ideal world I wouldn't have committed a security fix that caused
regressions, but it's not always feasible to avoid mistakes, particularly when
working under embargo with only a small number of possible reviewers.
CVE-2021-21261 is something I noticed while doing feature development (I
wasn't specifically looking for vulnerabilities), and I only found the regression
when I went back to working on the new feature.

No need to apologize. We are all human, and you are doing a lot more than most. :)

smcv and others added 2 commits January 27, 2022 02:22
Signed-off-by: Simon McVittie <[email protected]>
(backported from commit 86dd000)
(cherry picked from commit fb6f1ea)
For updates in remotes with a local (file:) uri we just do a deploy
with a LOCAL_PULL flag set and an empty arg_repo_path. However, our
arg_repo_path checking at some point seemed to stop properly handling
the case where it is empty. I got it to report "No such file" wich
broke the tests.

(cherry picked from commit 49e8bfc)
(cherry picked from commit c8b9069)
(cherry picked from commit 16290b5)

Fixes: flatpak#4339
@debarshiray debarshiray force-pushed the wip/rishi/CVE-2021-21261-CVE-2021-21381-CVE-2021-41133-1.6 branch from 5d30f3e to 29f606a Compare January 27, 2022 01:23
alexlarsson and others added 6 commits January 27, 2022 02:49
This adds a sleep(1) before each summary update (if there is a
pre-existing summary file). This avoids issues where a new summary
file get the same mtime (in seconds precision).

This is kind of a hacky work around, but it is good enought to get
the flatpak-1.8 branch working with latest ostree, and master has a better
fix already.

(cherry picked from commit 07e6a2c)
This avoids some of them being filtered out by a setuid bwrap. It also
means that if they came from an untrusted source, they cannot be used
to inject arbitrary code into a non-setuid bwrap via mechanisms like
LD_PRELOAD.

Because they get bundled into a memfd or temporary file, they do not
actually appear in argv, ensuring that they remain inaccessible to
processes running under a different uid (which is important if their
values are tokens or other secrets).

Signed-off-by: Simon McVittie <[email protected]>
Part-of: GHSA-4ppf-fxf6-vxg2
(cherry picked from commit dcd2494)
This checks that `flatpak run --env=` takes precedence over
`flatpak override --env=`, and that environment variables don't get
onto the bwrap command-line (which would be information disclosure
if their values are secret).

Signed-off-by: Simon McVittie <[email protected]>
Part-of: GHSA-4ppf-fxf6-vxg2
(cherry picked from commit 6a11007)
This allows environment variables to be added to the context without
making their values visible to processes running under a different uid,
which might be significant if the variable's value is a token or some
other secret value.

Signed-off-by: Simon McVittie <[email protected]>
Part-of: GHSA-4ppf-fxf6-vxg2
(cherry picked from commit 57416f3)
This hides overridden variables from the command-line, which means
processes running under other uids can't see them in /proc/*/cmdline,
which might be important if they contain secrets.

Signed-off-by: Simon McVittie <[email protected]>
Part-of: GHSA-4ppf-fxf6-vxg2
(backported from commit fb1eaef)
Signed-off-by: Simon McVittie <[email protected]>
Part-of: GHSA-4ppf-fxf6-vxg2
(cherry picked from commit 7bb78f8)
smcv and others added 21 commits January 27, 2022 02:49
If the caller specifies a variable that can be used to inject arbitrary
code into processes, we must not allow it to enter the environment
block used to run `flatpak run`, which runs unsandboxed.

This change requires the previous commit "context: Add --env-fd option",
which adds infrastructure used here.

To be secure, this change also requires the previous commit
"run: Convert all environment variables into bwrap arguments", which
protects a non-setuid bwrap(1) from the same attack.

Signed-off-by: Simon McVittie <[email protected]>
Part-of: GHSA-4ppf-fxf6-vxg2
(cherry picked from commit 26f09bf)
For the portal's use of --env-fd= to be safe, we want the environment
variables that it sets to end up in the environment for the program
that is run by `bwrap` as process 2, but they must not go into the
environment that gets used to run `flatpak run` or `bwrap`. Assert
that this is the case.

For completeness, we're testing both --env= and --env-fd= here,
even though the earlier commit
"portal: Do not use caller-supplied variables in environment"
always uses --env-fd=.

Part-of: GHSA-4ppf-fxf6-vxg2
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 5019b30)
We need a different rpath for libpreload in this case, because
installed_testdir is not set.

(cherry picked from commit e3d06dd)
This means we can systematically pass the environment variables
through bwrap(1), even if it is setuid and thus is filtering out
security-sensitive environment variables. bwrap itself ends up being
run with an empty environment instead.

This fixes a regression when CVE-2021-21261 was fixed: before the
CVE fixes, LD_LIBRARY_PATH would have been passed through like this
and appeared in the `flatpak build` shell, but during the CVE fixes,
the special case that protected LD_LIBRARY_PATH was removed in favour
of the more general flatpak_bwrap_envp_to_args(). That reasoning only
works if we use flatpak_bwrap_envp_to_args(), consistently, everywhere
that we run the potentially-setuid bwrap.

Fixes: 6d1773d "run: Convert all environment variables into bwrap arguments"
Resolves: flatpak#4080
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=980323
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 9a61d2c)
(cherry picked from commit 93ecea3)
This means we can systematically pass the environment variables
through bwrap(1), even if it is setuid and thus is filtering out
security-sensitive environment variables. bwrap ends up being
run with an empty environment instead.

As with the previous commit, this regressed while fixing CVE-2021-21261.

Fixes: 6d1773d "run: Convert all environment variables into bwrap arguments"
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit fb473ca)
(cherry picked from commit f91857c)
Fixes flatpak#4146.

(cherry picked from commit 652a28f)
(cherry picked from commit c54e7c3)
If we add new features analogous to file forwarding later, we might
find that we need a different magic token. Let's reserve the whole
@@* namespace so we can call it @@something-else.

Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 1e7e8fd)
(cherry picked from commit cc7526b)
This is either a malicious/compromised app trying to do an attack, or
a mistake that will break handling of %f, %u and so on. Either way,
if we refuse to export the .desktop file, resulting in installation
failing, then it makes the rejection more obvious than quietly
removing the magic tokens.

Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 46b3ede)
(cherry picked from commit 754450e)
The terms whitelist and blacklist are hurtful to some people, and per
our code of conduct Flatpak is an inclusive community. Replace them with
allowlist and blocklist which are also more clear. This terminology
change is being implemented more broadly in the software industry; see
e.g. https://go-review.googlesource.com/c/go/+/236857/

(cherry picked from commit a994cdb)
clone() is a mad syscall with about 4 different argument orders. While
most of them agree that argument 0 is flags, s390 and s390x have the
flags argument second - A0 is the child stack pointer there.

[smcv: Add an explanatory comment; also test __CRIS__ for completeness]

Bug-Debian: https://bugs.debian.org/964541
Bug-Ubuntu: https://launchpad.net/bugs/1886814
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 8ba141c)
(cherry picked from commit f4c3ea5)
At the moment, if we block a syscall we always make it fail with EPERM,
but this is risky: user-space libraries can start to use new replacements
for old syscalls at any time, and will often treat EPERM as a fatal error.
For new syscalls, we should make the syscall fail with ENOSYS, which is
indistinguishable from running on an older kernel and will cause fallback
to an older implementation, for example clone3() to clone().

In future we should probably move from EPERM to ENOSYS for some of the
syscalls we already block, but for now keep the status quo.

This is a prerequisite for fixing the vulnerability tracked as
GHSA-67h7-w3jq-vh4q.

Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 89f9bb7)
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 13d34f9)
Historically, syscalls could take arbitrarily-different values on
different architectures, but new syscalls are added with syscall numbers
that align on each architecture.

Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit cf9cdd9)
clone3() can be used to implement clone() with CLONE_NEWUSER, allowing
a sandboxed process to get CAP_SYS_ADMIN in a new namespace and
manipulate its root directory. We need to block this so that AF_UNIX-based
socket servers (X11, Wayland, etc.) can rely on
/proc/PID/root/.flatpak-info existing for all Flatpak-sandboxed apps.

Partially fixes GHSA-67h7-w3jq-vh4q.

Thanks: an anonymous reporter
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 08c65cd)
If we don't allow mount() then we shouldn't allow these either.

Partially fixes GHSA-67h7-w3jq-vh4q.

Thanks: an anonymous reporter
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit db4ccf7)
If we don't allow unshare() or clone() with CLONE_NEWUSER, we also
shouldn't allow joining an existing (but different) namespace.

Partially fixes GHSA-67h7-w3jq-vh4q.

Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit a01fc5f)
If we don't allow mounting filesystems, we shouldn't allow unmounting
either.

Partially fixes GHSA-67h7-w3jq-vh4q.

Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 758b8ca)
If we don't allow pivot_root() then there seems no reason why we should
allow chroot().

Partially fixes GHSA-67h7-w3jq-vh4q.

Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 8f87696)
The error-handling here was

    if (r < 0 && r == -EFAULT)

but Alex says it was almost certainly intended to be

    if (r < 0 && r != -EFAULT)

so that syscalls not known to libseccomp are not a fatal error.

Instead of literally making that change, emit a debug message on -EFAULT
so we can see what is going on.

This temporarily weakens our defence against CVE-2021-41133
(GHSA-67h7-w3jq-vh4q) in order to avoid regressions: if the installed
version of libseccomp does not know about the recently-added syscalls,
but the kernel does, then we will not prevent non-native executables
from using those syscalls.

Resolves: flatpak#4458
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit d419fa6)
(cherry picked from commit 270701f)
(cherry picked from commit a0055e4)
This was incorrectly looking at errno instead of -r.

Fixes: 0b38b0f "run: Handle unknown syscalls as intended"
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 3fc8c67)
(cherry picked from commit 97e128c)
(cherry picked from commit da503e0)
Signed-off-by: Simon McVittie <[email protected]>
(cherry picked from commit 53bde36)
(cherry picked from commit bd2c58f)
(cherry picked from commit adaa025)
@debarshiray debarshiray force-pushed the wip/rishi/CVE-2021-21261-CVE-2021-21381-CVE-2021-41133-1.6 branch from 29f606a to d2e12d0 Compare January 27, 2022 01:51
@debarshiray
Copy link
Contributor Author

Ping.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants