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: add zigbee-dongle interface #1405
Conversation
} | ||
} | ||
|
||
func (iface *ZigbeeDongleInterface) zigbeeDevPaths(slot *interfaces.Slot) ([]string, error) { |
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 mentioned in private, my only issue with this pull request is that it grants access to all zigbee dongles. While I recognize the issue that currently we con't have a way to create dynamic slots (nothing like hot plug) I worry that later on we may have to say the zigbee-dongle
interface is now constrained to a particular dongle (in the unlikely case of there being more than one). I'd prefer if we either 1) only allowed one (say, the one with the smallest serial number) or 2) renamed the interface to something broader like zibgee-dongles
.
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.
Happy to do the second option here
Marking as blocked because we really have to figure out something better to do with udev. |
Per the online discussion. I'd like to merge this today and address udev issues that also affect modem-manager in a separate pull request. |
whitelist this please |
func (iface *ZigbeeDongleInterface) ConnectedPlugSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) { | ||
switch securitySystem { | ||
case interfaces.SecurityAppArmor: | ||
paths, err := iface.zigbeeDevPaths(slot) |
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.
Why are we doing this instead of simply using the glob itself in the apparmor profile?
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.
Note that this will break if the device is hot-plugged afterwards.
LGTM assuming that the glob situation is fixed per comment above. |
Can one of the admins verify this patch? |
1 similar comment
Can one of the admins verify this patch? |
@niemeyer I used this approach based on the following:
Hence this code means I only add dereferenced paths to devices that I know are zigbee dongles in to the apparmor snippet. |
var zigbeeDonglePermanentSlotUdev = []byte(` | ||
IMPORT{builtin}="usb_id" | ||
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idProduct}=="0003", ATTRS{idVendor}=="10c4", SYMLINK+="zigbee/$env{ID_SERIAL}" | ||
`) |
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.
So, this might be the time to use the Udev backend for one of its initial design goals: adding devices to an app-specific device cgroup. This would address the concerns of @zyga and allow fine-grained control. Here is how it could work:
- this interface has attributes for idProduct and idVendor (feel free to name the yaml keys something different of course)
- when attributes are used, fill in ATTRS{idProduct} and ATTRS{idVendor} appropriately, add a TAG+="snap_connecting_app" for each connected plug. udev TAGs cannot use globs so you'll need a rule for each. The TAG to add is simply the security label for the plug replacing '.' with '_'. Use /dev/** for apparmor.
- if it makes sense, when attributes are not used, don't add TAGs and simply add all known idProducts and idVendors for zigbee devices to zigbeeDonglePermanentSlotUdev and use /dev/zigbee/* for apparmor
What does this do and why does it work? When attributes are not used, then access is granted to all known zigbee devices and this access is enforced with the /dev/zigbee/* apparmor glob rule. When attributes are used, access is granted only to those devices matching the idProduct and idVendor and this is enforced by adding only those devices that are udev TAGged for this app to the snap's device cgroup (we use a /dev/** apparmor rule since we rely on the device cgroup for security instead of apparmor). In both cases hot plugging and unplugging should work as expected.
A consideration with this approach is that using this interface with other interfaces that grant access to /dev/* via apparmor means that those other devices won't be in the device cgroup. For example, suppose we have the following yaml:
plugs:
- camera
- zigbee
id-product: "0003"
id-vendor: "10c4"
With the above we end up with apparmor policy (which while /dev/video0 is redundant, is still valid):
/dev/video0 rw,
/dev/** rw,
but only the zigbee devices are added to the device cgroup so while apparmor allows access to /dev/video0, the snap won't be able to access /dev/video0 because /dev/video0 wasn't udev TAGged and therefore snap-confine didn't add it to the per-app device cgroup. Importantly, this issue will not be unique to the zigbee interface-- it will need to be fixed to support TAGging for any interface that intends to use device cgroups and I think will be particularly important for gadget snap device labelling, etc.
OTOH to fix this we would have to abstract out the /dev/ accesses that are sprinkled through the interfaces and for each encode both an apparmor rule and a udev snippet in the interfaces, then when generating the security policy detect when a device cgroup will be used and add the udev snippets when it is and the apparmor rules when not.
Since the default with no attributes is this PR, perhaps it would make sense to commit this as is (ie, just the /dev/zigbee/* apparmor rule) and then work through attributes and specific device assignment in a future PR. As such, I agree this should not be renamed zigbee-dongles.
16:20 <joc_> jdstrand: thanks for response on zigbee-dongle, can i just check one point |
Can one of the admins verify this patch? |
1 similar comment
Can one of the admins verify this patch? |
18:23 joc_: It should at least do what I suggested in terms of using apparmor rather than globbing the FS at connection time |
f960382
to
bb97b90
Compare
I've made an attempt to implement what @jdstrand suggested on another branch. Currently missing https://github.com/jocave/snapd/commits/interface-zigbee-dongle-with-cgroups |
bb97b90
to
53f8b8c
Compare
Heh, I just noticed that the irc paste from last month was wrong (what was said was correct, but who said it got mixed up). This is what it should be: "16:20 joc_: thanks for response on zigbee-dongle, can i just check one point |
An interface that allows a usb removable zigbee dongle to be exposed through plugs & slots.
At the moment this only supports one of these devices as indicated by the udev snippet.
Any plug which is connected to a slot of this type would gain the AppArmor permissions to read&write to the device node of any and all devices the interface supports (no matter how many are attached to the system).