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: Add USB block / allowlist #5620
base: main
Are you sure you want to change the base?
Conversation
Are we sure app maintainers or end users will understand what those permissions do and how to manage them? It's not quite human readable format. |
e151230
to
43cff99
Compare
App maintainers who write apps that use USB devices surely know what vendor id and product id are. Users are expected to interact with portal requests, which have human-readable device names. |
90c5dff
to
284b4a4
Compare
This work can be verified by building this branch of Boatswain: https://gitlab.gnome.org/World/boatswain/-/tree/gbsneto/usb-manifest After checking out this branch, you can run the following command to build it: Then you can verify that this PR properly sets the
At the bottom of the file there should be the following:
If you run Boatswain with
|
284b4a4
to
b1ee7fe
Compare
Damn, I pushed by mistake, sorry for disrupting the review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this looks good to me (pending single discussion). I think this is a better approach than #5612.
I'll leave this open for a bit for others to chime in.
It was mentioned that usb.ids exists to map these IDs to a somewhat readable value. Frontend tools can use this in the future. However for the permission itself that isn't usable. |
b1ee7fe
to
45c3f26
Compare
The testing steps described at #5620 (comment) still work with the last push 👍 |
The corresponding USB portal which actually uses this information can be found here: flatpak/xdg-desktop-portal#1238 |
Does the fact flatpak exposes various paths under |
That's looks a separate issue. It should be addressed separately. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not review the code itself, and my analysis of requirements might not be complete.
I would advise focusing first on the portal and its implementation, and its ability to authorise and revoke access to devices as a priority, as the flatpak changes only really modify device enumeration.
doc/flatpak-run.xml
Outdated
|
||
<listitem><para> | ||
Adds a USB device to the list of allowed devices. | ||
<arg choice="plain">VENDOR_ID</arg> must be a valid vendor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every time you mention the vendor or product IDs, you should mention in which format they will be parsed. Here it seems like the only format permitted is hex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to document the exact supported syntax for vendor and product ids, and device classes and subclasses. Does it look better now?
doc/flatpak-build-finish.xml
Outdated
<term><option>--usb=VENDOR_ID:PRODUCT_ID</option></term> | ||
|
||
<listitem><para> | ||
Adds a USB device to the list of allowed devices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes it seem like "allowed devices" will be available to the application without going through a portal. The fact that a portal is necessary needs to be mentioned. This also probably needs to be reworded because they're not going to be blocked by the portal, but not listed in the portal's enumeration instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to mention that this is used by the USB portal in the documentation. How does it read to you now?
doc/flatpak-build-finish.xml
Outdated
@@ -284,6 +284,31 @@ key=v1;v2; | |||
</para></listitem> | |||
</varlistentry> | |||
|
|||
<varlistentry> | |||
<term><option>--usb=VENDOR_ID:PRODUCT_ID</option></term> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having this be only available as a finish-args
is close to unmaintainable for app developers with more than a few supported devices. For example, this is the list of devices supported by libfprint (and its Flatpak demo application that talks USB directly): https://fprint.freedesktop.org/supported-devices.html
It would be necessary to have the ability to import the list from an outside source, such as a plain text file, or a manifest snippet, for any serious use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be done in the flatpak-builder layer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also strikes me as somewhat inefficient to list such large lists as part of the metadata. Do we expect a scanner app to display this entire list on the commandline when you install it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably not efficient, yeah; but I don't have a clear picture of viable options here. I mean, Flatpak could have an extra /.flatpak-usb-devices
file, but it's probably going to be equally as large and, probably, equally as annoying. Another alternative is a new binary format for this file, which sounds like an overkill to me.
Is there any particular approach you'd like to see explored in this branch?
<term><option>allowed-devices</option> (string list)</term> | ||
<listitem><para> | ||
List of allowed USB devices. Each element of can be composed | ||
of "VENDOR_ID:PRODUCT_ID", or "VENDOR_ID:*". Available since |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to "allowlist" all USB devices, which would be necessary for WebUSB support in Chromium-based browsers. If devices aren't listed, they wouldn't be enumerated, and couldn't be accessed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A common requirement for enumerating USB devices is based on the class, or interface identifiers. For example, if you wanted direct access to all devices with a "network" USB interface, this doesn't seem to allow it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left that out somewhat on purpose, because I wanted to think better about how to handle these different queries through the command line. So far there is:
- Specific device:
--usb=AAAA:BBBB
- All devices from specific vendor:
--usb=AAAA:*
For class and subclass queries, I can imagine the following options:
--usb=class=AA:[BB|*]
--usb-class=AA:[BB|*]
--usb=AA:[BB|*]
I personally prefer (1) and (2). However, does that mean devices and vendor queries need to be adjusted into --usb=device=AAAA:BBBB
, and --usb=vendor=AAAA
? It looks a bit convoluted to me.
An option for allowlisting all devices is --usb=*:*
. Or a contracted form, --usb=*
.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe the usb selector could be made more generic.
Say, a per element prefix of dev/cls/vnd, and maybe allow combinations.
So cls:AA:*+vnd=BB
. We could have a generic --usb argument taking these, or helper --usb-device=... that constructs the generic key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion @alexlarsson, I'll try and implement that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this last push, I've applied this cls
/vnd
/dev
syntax to --usb
and --no-usb
. Some rules apply here:
--usb=all
must not have any further rules (e.g.--usb=all+vnd:0fd9
is in valid). There are tests for that.dev
rules must have avnd
rule together, butvnd
is okay to not have a matchingdev
. e.g.--usb=vnd:0fd9
is valid,--usb=vnd:0fd9+dev:0060
is valid, but --usb=dev:0060` is invalid. There are tests for that.cls
rules can be freely applied on top ofdev
andvnd
. There are tests for that.
Notice that I haven't yet added the helper --usb-device
. If people seem satisfied with this approach, I'll be happy to add the helper 🙂
Please let me know what you think!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentionnd in the other thread #5620 (comment)
I can see issues about using *
in any of the command line arguments.
if (!g_hash_table_contains (new->blocked_usb_devices, value)) | ||
return TRUE; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could potentially be smarter wrt globs. I.e. don't warn when aa:bb was removed, but aa:* was added. Not sure how important this is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably good to have. I'll look into adding it.
One thing i worry about here is the messaging. It looks like allowed-device means that the usb device access is allowed, but really it just means it is discoverable. We need both the cli options, the metadata key names and the part displayed during install to make this more obvious. |
45c3f26
to
45afd8d
Compare
This is how the Flatpak manifest of my little Stream Deck app looks with this branch: https://gitlab.gnome.org/World/boatswain/-/merge_requests/25 I feel like it's certainly missing flatpak-builder integration in the JSON file. Happy to add support for that once we're settled with something on Flatpak itself. Still to-do in this branch, in no particular order:
|
common/flatpak-context.c
Outdated
@@ -1531,6 +1970,8 @@ static GOptionEntry context_options[] = { | |||
{ "system-no-talk-name", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_system_no_talk_name_cb, N_("Don't allow app to talk to name on the system bus"), N_("DBUS_NAME") }, | |||
{ "add-policy", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_add_generic_policy_cb, N_("Add generic policy option"), N_("SUBSYSTEM.KEY=VALUE") }, | |||
{ "remove-policy", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_remove_generic_policy_cb, N_("Remove generic policy option"), N_("SUBSYSTEM.KEY=VALUE") }, | |||
{ "usb", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_usb_cb, N_("Add USB device to allowlist"), N_("VENDOR_ID:PRODUCT_ID") }, | |||
{ "no-usb", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK, &option_no_usb_cb, N_("Add USB device to blocklist"), N_("VENDOR_ID:PRODUCT_ID") }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have nodevice
, nosocket
and nofilesystem
so I think this should be nousb
, for consistency.
doc/flatpak-run.xml
Outdated
@@ -752,6 +820,9 @@ key=v1;v2; | |||
<para> | |||
<command>$ flatpak run --command=bash org.gnome.Sdk</command> | |||
</para> | |||
<para> | |||
<command>$ flatpak run org.gnome.Boxes --no-usb=0fd9:*</command> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an issue using *
here is that on most shell the expression is expanded.
Here on zsh:
% flatpak run org.gnome.Boxes --nousb=0fd9:*
zsh: no matches found: --nousb=0fd9:*
This works though:
<command>$ flatpak run org.gnome.Boxes --no-usb=0fd9:*</command> | |
<command>$ flatpak run org.gnome.Boxes --no-usb=0fd9:\*</command> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe instead the syntax could be VEND:
for "all devices from vendor VEND"
doc/flatpak-run.xml
Outdated
A device class and subclass query. <arg choice="plain">DATA</arg> | ||
must be in the form of <arg choice="plain">CLASS:SUBCLASS</arg> where | ||
both <arg choice="plain">CLASS</arg> and <arg choice="plain">SUBCLASS</arg> | ||
must valid 2-digit hexadecimal class id numbers. Alternatively, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
must valid 2-digit hexadecimal class id numbers. Alternatively, | |
must be a valid 2-digit hexadecimal class id number. Alternatively, |
doc/flatpak-run.xml
Outdated
|
||
<listitem><para> | ||
A device product id query. <arg choice="plain">DATA</arg> | ||
must be a valid 4-character hexadecimal product id number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
must be a valid 4-character hexadecimal product id number | |
must be a valid 4-digit hexadecimal product id number |
doc/flatpak-run.xml
Outdated
|
||
<listitem><para> | ||
A device vendor id query. <arg choice="plain">DATA</arg> | ||
must be a valid 4-character hexadecimal vendor id number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
must be a valid 4-character hexadecimal vendor id number | |
must be a valid 4-digit hexadecimal vendor id number |
Also I have a concern about the syntax: I have 332 rules here for Epson Scan 2: I parsed the .rules with python. It's tedious to add to the manifest. |
A libgphoto2 device list is 2595 long. |
This original branch is at |
4b791dd
to
e765beb
Compare
rebased (a second time and added some fixes) |
Giving access to all devices of one vendor is a mistake. If the vendor starts making a smartcard, fido device, etc, the app suddenly has access to this and there is no way for a human reviewing the manifest to figure out if all devices of a vendor makes sense for this specific app. |
Add '--usb' and '--no-usb' to the FlatpakContext option group. Map these parameters to either the list, or the blocklist, of a new "USB Devices" group in the metadata key file. It looks like this: ``` [USB Devices] blocked-devices=cls:01:*; allowed-devices=vnd:0fd9+dev:0080;vnd:0fd9+dev:0080; ``` Flatpak itself does not use these values, they're meant to be used by e.g. XDG Desktop Portal to filter which devices the app can see through the USB portal (work in progress). Blocked devices must always take precedence over allowed devices. This is heavily inspired by flatpak#4083
Signed-off-by: Hubert Figuière <[email protected]>
Signed-off-by: Hubert Figuière <[email protected]>
Signed-off-by: Hubert Figuière <[email protected]>
Also added test for the empty string query Signed-off-by: Hubert Figuière <[email protected]>
Signed-off-by: Hubert Figuière <[email protected]>
Signed-off-by: Hubert Figuière <[email protected]>
Add '--usb' and '--no-usb' to the FlatpakContext option group.
Map these parameters to either the list, or the blocklist, of a new "USB Devices" group in the metadata key file. It looks like this:
Flatpak itself does not use these values, they're meant to be used by e.g. XDG Desktop Portal to filter which devices the app can see through the USB portal (work in progress).
Blocked devices must always take precedence over allowed devices.
This is heavily inspired by #4083
This is an alternative to exporting portal files (see #5612)