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

interfaces/many: deny arbitrary desktop files and misc from /usr/share #8301

Conversation

jdstrand
Copy link

@jdstrand jdstrand commented Mar 19, 2020

This implements option 'E' from
https://bugs.launchpad.net/snapd/+bug/1868051/comments/1.

Please see individual commit comments for more details.

Jamie Strandboge added 4 commits March 19, 2020 19:17
Currently, the desktop interface allows access to all of
/usr/share/applications. The files in /usr/share/applications come from
the core snaps, and with the exception of files related to xdg-open,
snaps are unable to do anything useful with these files (since they are
unable to execute the application). As such, limit the access to:

  /usr/share/applications/ r,
  /usr/share/applications/mimeapps.list r,
  /usr/share/applications/xdg-open.desktop r,

and suppress noisy denials by adding explicit deny rules for the desktop
files known to be shipped in the core, core18 and core20 snaps.

References:
https://bugs.launchpad.net/snapd/+bug/1868051 (related)
Currently, the unity7 interface allows access to all of
/usr/share/applications. The files in /usr/share/applications come from
the core snaps, and with the exception of files related to xdg-open,
snaps are unable to do anything useful with these files (since they are
unable to execute the application). As such, limit the access to:

  /usr/share/applications/ r,
  /usr/share/applications/mimeapps.list r,
  /usr/share/applications/xdg-open.desktop r,

and suppress noisy denials by adding explicit deny rules for the desktop
files known to be shipped in the core, core18 and core20 snaps.

In addition, to avoid confusion, remove legacy rules inherited from
snappy 15.04 that do not exist in the core, core18 and core20 snaps:

  /usr/share/gnome/applications/
  /usr/share/applications/mimeinfo.cache
  /usr/share/unity/icons/**
  /usr/share/thumbnailer/icons/**
  /usr/share/themes/**
  /usr/share/gnome/glib*/schemas/{,*}
  /usr/share/ubuntu/glib*/schemas/{,*}

References:
https://bugs.launchpad.net/snapd/+bug/1868051 (related)
Currently, for historical reasons the browser-support interface allows
access to /usr/share/applications and /var/lib/snapd/desktop/applications
when allow-sandbox: true. With the exception of files related to
xdg-open from the core snaps for /usr/share/applications and the snap's
own desktop file in /var/lib/snapd/desktop/applications, browser snaps
are unable to do anything useful with these files. This has led to
situations where browsers are suggesting things they shouldn't and
broken GLib portals support.

While the desktop interface has been updated to limit access to
/usr/share/applications and all applications that plugs browser-support
should typically also plugs 'desktop', there is an existing snap that
plugs browser-support with allow-sandbox: true without 'desktop' or
'unity7', so we duplicate those accesses here.

While the desktop-legacy interface allows access to the directory read
of /var/lib/snapd/desktop/applications and the snap's own desktop file
in this directory, desktop-legacy is a transitional interface that
shouldn't be required for snaps plugging browser-support, so those rules
are duplicated here.

References:
https://bugs.launchpad.net/snapd/+bug/1868051
@jdstrand
Copy link
Author

Marking as blocked until @jhenstridge (and optionally @kenvandine) can comment.

@jdstrand jdstrand added this to the 2.45 milestone Mar 19, 2020
@codecov-io
Copy link

Codecov Report

Merging #8301 into master will decrease coverage by 0.02%.
The diff coverage is 67.74%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #8301      +/-   ##
==========================================
- Coverage   80.68%   80.66%   -0.03%     
==========================================
  Files         723      723              
  Lines       57550    57602      +52     
==========================================
+ Hits        46435    46464      +29     
- Misses       7493     7508      +15     
- Partials     3622     3630       +8     
Impacted Files Coverage Δ
cmd/snap-bootstrap/bootstrap/bootstrap.go 49.38% <0.00%> (-1.26%) ⬇️
cmd/snap-bootstrap/main.go 40.74% <0.00%> (-1.57%) ⬇️
interfaces/builtin/browser_support.go 76.47% <ø> (ø)
interfaces/builtin/desktop.go 95.83% <ø> (ø)
interfaces/builtin/desktop_legacy.go 100.00% <ø> (ø)
interfaces/builtin/unity7.go 65.00% <ø> (ø)
cmd/snap-bootstrap/partition/sfdisk.go 76.53% <71.18%> (-4.24%) ⬇️
osutil/synctree.go 76.82% <0.00%> (-2.44%) ⬇️
cmd/snap/cmd_debug_state.go 66.87% <0.00%> (-0.64%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bd78648...6464c63. Read the comment docs.

@jhenstridge
Copy link
Contributor

In general this looks good, but I think it should be safe to deny access to /var/lib/snapd/desktop/applications completely. As mentioned in a followup to the bug report, the reasoning related to BAMF_DESKTOP_FILE_HINT does not sound correct, as that environment variable is checked out of process.

If you're worried about the number of snaps we'd have to test, perhaps just deny access in the browser-support/allow-sandbox case for now, and we can work from there.

Reading /var/lib/snapd/desktop/applications is required by at least
unity messaging and xdg-mime. Update the comments for desktop,
desktop-legacy and browser-support to reflect this (and no longer
reference BAMF_DESKTOP_FILE_HINT since that comment was wrong).

Explicitly deny /var/lib/snapd/desktop/applications/mimeinfo.cache since
snaps are unable to use the data in this file (since they can't execute
the returned desktop file themselves). unity messaging menu doesn't
require mimeinfo.cache and xdg-mime will fallback to reading the desktop
files directly to look for MimeType. Since reading the snap's own
desktop files is allowed, we can safely deny access to mimeinfo.cache
(eg, xdg-mime will either return one of the snap's mimetypes, or none).
@jdstrand
Copy link
Author

In general this looks good, but I think it should be safe to deny access to /var/lib/snapd/desktop/applications completely. As mentioned in a followup to the bug report, the reasoning related to BAMF_DESKTOP_FILE_HINT does not sound correct, as that environment variable is checked out of process.

If you're worried about the number of snaps we'd have to test, perhaps just deny access in the browser-support/allow-sandbox case for now, and we can work from there.

Ok, yes, thank you for mentioning BAMF_DESKTOP_FILE_HINT. I did some digging and figured out that the reason why this is actually needed is to support the unity messaging menu (confirmed via the hello-unity snap) and also xdg-mime (I dug up that the denial that initially prompted the addition of these rules was the discord snap calling xdg-mime).

I just pushed a commit that adjusts the comment to mention unity messaging and xdg-mime. I confirmed that neither need access to mimeinfo.cache so I created a deny rule for it. I also confirmed that @{SNAP_INSTANCE_NAME}_*.desktop is required for unity messaging so I'm leaving that in browser-support so as not to break snaps that use allow-sandbox: true without these desktop interfaces (there are production snaps in the store that do this) and for those that choose to use the messaging menu (eg, thunderbird would require allow-sandbox: true and could use this feature).

@jhenstridge - can you take another look? I believe this is still compatible with fixing portals since an application that specifies MimeType in its own desktop file is likely to just act on that mime type and not reach out to portals. Eg, firefox isn't going to ask portals to find an application to act on text/html since it will do it itself (and if it does, that is a corner case?). If this is not the case, we'll have to discuss how to handle this situation since we cannot remove the rules without regressing applications (also note, removing from browser-support only doesn't really help since most of the browsers are also plugging desktop-legacy and/or unity7 (confirmed be looking at brave, chromium, firefox, opera{-beta,-developer}, thunderbird, and webbrowser-app

@jdstrand
Copy link
Author

jdstrand commented Mar 20, 2020

@{SNAP_INSTANCE_NAME}_*.desktop is required for unity messaging so I'm leaving that in browser-support so as not to break snaps that use allow-sandbox: true without these desktop interfaces (there are production snaps in the store that do this) and for those that choose to use the messaging menu (eg, thunderbird would require allow-sandbox: true and could use this feature).

Actually, thinking through this more, browser-support can remove the access after all without regression because an application that uses the unity messaging menu necessarily must also plugs one of desktop-legacy or unity7 for the dbus accesses. I'll remove this now, but note that it doesn't change the fact that the browsers that are going to use portals are already plugging desktop-legacy and/or unity7 and getting the accesses that way.

In thinking through why /var/lib/snapd/desktop/applications is needed
(for not regressing unity messaging menu), the snap necessarily must
plugs desktop-legacy and/or unity7 in order to have the dbus accesses.
Snaps that currently plugs browser-support with allow-sandbox: true
cannot regress this functionality because they already do not have it.
As such, remove the accesses to /var/lib/snapd/desktop/applications.
@Erick555
Copy link
Contributor

@jdstrand can't the follow-up be done as part of those changes? As I understand this alone will result in dozens of of denials every time app is launched.

@jhenstridge
Copy link
Contributor

Ok, yes, thank you for mentioning BAMF_DESKTOP_FILE_HINT. I did some digging and figured out that the reason why this is actually needed is to support the unity messaging menu (confirmed via the hello-unity snap) and also xdg-mime (I dug up that the denial that initially prompted the addition of these rules was the discord snap calling xdg-mime).

I just pushed a commit that adjusts the comment to mention unity messaging and xdg-mime. I confirmed that neither need access to mimeinfo.cache so I created a deny rule for it. I also confirmed that @{SNAP_INSTANCE_NAME}_*.desktop is required for unity messaging so I'm leaving that in browser-support so as not to break snaps that use allow-sandbox: true without these desktop interfaces (there are production snaps in the store that do this) and for those that choose to use the messaging menu (eg, thunderbird would require allow-sandbox: true and could use this feature).

I had missed the messaging menu's separate client library. I had thought libunity was the client library for all these APIs, but that's obviously not the case.

The code in libmessaging-menu is a bit weird: it creates a GDesktopAppInfo by loading the desktop_id provided by the caller, and then all it does with that object is get its associated desktop_id. It certainly looks like they could avoid the access all together. I wonder if it would be worth allowing this only in unity7 and not desktop-legacy?

For the Discord snap, the use of the xdg-mime utility seems to be indirect. As a proprietary app, I can't see the source, but it looks like it might have calls to xdg-settings (a tool to check and alter mime type associations) and xdg-email (to open the user's preferred email client). The snap explicitly stages xdg-utils, so overrrides anything provided in the base snap for these:

https://github.com/snapcrafters/discord/blob/master/snap/snapcraft.yaml#L49

So rather than calling xdg-settings proxy provided by core/core18 that will actually do something useful, it calls a shell script that won't. As for xdg-email, I doubt the version bundled in the snap can function. We have an open bug report for providing a proxy for this too:

https://bugs.launchpad.net/snapd/+bug/1863625

So it isn't clear that the Discord snap is a good argument for providing this access: if anything, providing access masks the fact that the snap is not functioning correctly.

@jhenstridge - can you take another look? I believe this is still compatible with fixing portals since an application that specifies MimeType in its own desktop file is likely to just act on that mime type and not reach out to portals. Eg, firefox isn't going to ask portals to find an application to act on text/html since it will do it itself (and if it does, that is a corner case?).

I've been testing Firefox's portal support, and it will use its own internal handlers before calling out to the glib APIs that check desktop files. So xdg-open.desktop claiming the http and https schemes isn't a problem.

@jdstrand
Copy link
Author

jdstrand commented Apr 7, 2020

Thanks @jhenstridge. Marking this as unblocked now. Note to other reviewers: the xdg-mime and unity messaging changes could happen in a follow-up PR, however, as @Erick555 mentioned, we should probably either in this PR or a followup (but both for 2.45) implement option 'E' from https://bugs.launchpad.net/snapd/+bug/1868051/comments/1 (which is this PR plus allowing reading the snap's desktop files with explicit denies for everything else), which happens to address the xdg-mime comment and @Erick555's concern.

I will work on that. If it is done before others review this PR, I will add it to this one, else, create another.

Jamie Strandboge added 5 commits June 1, 2020 19:59
getDesktopFileRules(<snap instance name>) generates snippet rules for
allowing access to the specified snap's desktop files in
dirs.SnapDesktopFilesDir, but explicitly denies access to all other
snaps' desktop files since xdg libraries may try to read all the desktop
files in the dir, causing excessive log noise.

Reference:
https://launchpad.net/bugs/1868051
desktop-legacy allowed reads on /var/lib/snapd/desktop/applications/ and
/var/lib/snapd/desktop/applications/@{SNAP_INSTANCE_NAME}_*.desktop.
Now, in addition to those accesses, explicitly deny access to other
snap's desktop files.
unity7 allowed reads on /var/lib/snapd/desktop/applications/ and
/var/lib/snapd/desktop/applications/@{SNAP_INSTANCE_NAME}_*.desktop.
Now, in addition to those accesses, explicitly deny access to other
snap's desktop files.
@jdstrand
Copy link
Author

jdstrand commented Jun 1, 2020

Ok, everything is implemented. This should fix the browser issue, not regress anything plugging desktop-legacy/unity7 and suppress noisy denials.

@mvo5 - this was one of the things that I was hoping to have in 2.45.1 for policy updates. @kenvandine in particular is wanting it. I believe there is very little chance of regression since browsers are currently all plugging desktop-legacy in addition to browser-support with 'allow-sandbox: true', so they'll still have read access to /var/lib/snapd/desktop/applications and their own desktop file(s), but not other snaps (which is what the fix is for). Snaps only plugging desktop-legacy and/or unity7 have the same policy as before, except with some explict deny rules to silence noisy denials. As such, I changed the milestone back to 2.45. Please let me know if this is in error.

@jdstrand jdstrand modified the milestones: 2.46, 2.45 Jun 1, 2020
@kenvandine
Copy link
Contributor

I am very keen to see this land. The Firefox snap revision that would benefit from this is already in the candidate channel. In fact I think the Firefox experience slightly regresses with the current snapd. This would be a big improvement.

@jdstrand
Copy link
Author

jdstrand commented Jun 2, 2020

FYI, the failures were unrelated so I restarted the jobs. It sure would be nice to just re-run the failing group of tests....

jdstrand pushed a commit to jdstrand/snapd that referenced this pull request Aug 14, 2020
These days desktop files are written as name+instance_command.desktop
instead of name_instance_command.desktop. wrappers/desktop.go was
calculating the desktop file correctly, but other parts of the code base
are not. By moving to a SnapInfo method, these other parts can migrate
with everything using the same code to calculate the desktop file name.

References:
- canonical#8301 (comment)
Jamie Strandboge added 8 commits August 14, 2020 21:00
These days desktop files are written as name+instance_command.desktop
instead of name_instance_command.desktop. wrappers/desktop.go was
calculating the desktop file correctly, but other parts of the code base
are not. By moving to a SnapInfo method, these other parts can migrate
with everything using the same code to calculate the desktop file name.

References:
- canonical#8301 (comment)
The desktop-legacy and unity7 policy was incorrectly using
@{SNAP_INSTANCE_NAME}_*.desktop which is name_instance_app.desktop, but
instance desktop files use name+instance_app.desktop now. Add a new
template var, @{SNAP_INSTANCE_DESKTOP}, and use it instead.
With standard hello-unity snap, we can see via dbus-monitor that
indicator-messages uses for the hello-unity_hello-unity.desktop file:

  /com/canonical/indicator/messages/hello_unity_hello_unity_desktop

and modifying hello-unity to understand hello-unity_foo (with the
desktop file written as hello-unity+foo_hello-unity.desktop) it uses:

  /com/canonical/indicator/messages/hello_unity_foo_hello_unity_desktop

Adjust the policy and add tests for this.
@jdstrand
Copy link
Author

@jhenstridge and @anonymouse64 - I believe I've addressed all feedback. This PR includes #9167 so you may want to review that one first. Thanks!

@jdstrand
Copy link
Author

jdstrand commented Aug 15, 2020

FYI, I re-tested this with:

  • firefox --candidate on focal (see https://bugs.launchpad.net/snapd/+bug/1868051/comments/5) and this fixes the bug
  • discord on focal (it uses browser-support without allow-sandbox: true along with desktop-legacy and unity7. The added explicit denies for other snaps' desktop files did their job and discord appears to run correctly
  • hello-unity on xenial/unity (since it needs a running indicator-messages) and the messaging menu continues to work

In each I also ran 'snap run --shell ' and verified I could ls /var/lib/snapd/desktop/applications, access the snap's desktop file, but not be able to access other snap's desktop files (with no logging). I then did a parallel install and with 'snap run --shell' the snap can correctly access the instance's desktop file, but not the non-instance or other desktop files. Ie, it is all working as intended.

Copy link
Contributor

@jhenstridge jhenstridge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, subject to review comments on #9167.

@@ -80,22 +78,29 @@ owner @{HOME}/.local/share/fonts/{,**} r,
/usr/share/icons/*/index.theme rk,
/usr/share/pixmaps/ r,
/usr/share/pixmaps/** r,
/usr/share/unity/icons/** r,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This access is removed but not added anywhere back AFAICT - is there a regression risk here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. This path does not exist in core images (notice is is in /usr, which comes from core* snaps). This is explained in commit 105b47f:

    interfaces/unity7: limit access to /usr/share
    
    Currently, the unity7 interface allows access to all of
    /usr/share/applications. The files in /usr/share/applications come from
    the core snaps, and with the exception of files related to xdg-open,
    snaps are unable to do anything useful with these files (since they are
    unable to execute the application). As such, limit the access to:
    
      /usr/share/applications/ r,
      /usr/share/applications/mimeapps.list r,
      /usr/share/applications/xdg-open.desktop r,
    
    and suppress noisy denials by adding explicit deny rules for the desktop
    files known to be shipped in the core, core18 and core20 snaps.
    
    In addition, to avoid confusion, remove legacy rules inherited from
    snappy 15.04 that do not exist in the core, core18 and core20 snaps:
    
      /usr/share/gnome/applications/
      /usr/share/applications/mimeinfo.cache
      /usr/share/unity/icons/**
      /usr/share/thumbnailer/icons/**
      /usr/share/themes/**
      /usr/share/gnome/glib*/schemas/{,*}
      /usr/share/ubuntu/glib*/schemas/{,*}
    
    References:
    https://bugs.launchpad.net/snapd/+bug/1868051 (related)

Copy link
Contributor

@mvo5 mvo5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, one minor suggestion/question inline but no blocker.

interfaces/builtin/utils.go Outdated Show resolved Hide resolved
@jdstrand
Copy link
Author

@mvo5 - the spread tests are failing due to this unrelated failure:

2020-08-19 04:30:59 Failed tasks: 4
    - google:ubuntu-16.04-64:tests/main/lxd:snapd_cgroup_both
    - google:ubuntu-16.04-64:tests/main/lxd:snapd_cgroup_just_inside
    - google:ubuntu-16.04-64:tests/main/lxd:snapd_cgroup_just_outside
    - google:ubuntu-16.04-64:tests/main/lxd:snapd_cgroup_neither

This is ready for review.

@mvo5 mvo5 merged commit d712f52 into canonical:master Aug 20, 2020
jdstrand pushed a commit to jdstrand/snapd that referenced this pull request Aug 20, 2020
These days desktop files are written as name+instance_command.desktop
instead of name_instance_command.desktop. wrappers/desktop.go was
calculating the desktop file correctly, but other parts of the code base
are not. By moving to a SnapInfo method, these other parts can migrate
with everything using the same code to calculate the desktop file name.

References:
- canonical#8301 (comment)
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.

8 participants