Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
interfaces/builtin: use udev tagging more broadly #3617
Conversation
adglkh
added some commits
Jul 12, 2017
adglkh
referenced this pull request
Jul 25, 2017
Closed
Using udev tagging for snap interfaces #3587
| func init() { | ||
| - registerIface(&commonInterface{ |
mvo5
Jul 27, 2017
Collaborator
A bit of a meta-question - would it make sense to add an optional connectedPlugUdev to commonInterface so that not all the interfaces that use commonInterface need to be exapnded ?
adglkh
Jul 27, 2017
Contributor
Yes, it makes sense for some interfaces.
I'll fix it in the next commit.
Thanks.
adglkh
added some commits
Jul 27, 2017
codecov-io
commented
Jul 28, 2017
•
Codecov Report
@@ Coverage Diff @@
## master #3617 +/- ##
=========================================
+ Coverage 75.63% 75.7% +0.06%
=========================================
Files 407 407
Lines 35034 35093 +59
=========================================
+ Hits 26499 26566 +67
+ Misses 6654 6648 -6
+ Partials 1881 1879 -2
Continue to review full report at Codecov.
|
|
@adglkh - unfortunately there are more conflicts. Can you clean these up (again)? |
adglkh
added some commits
Aug 2, 2017
| @@ -1,7 +1,7 @@ | ||
| // -*- Mode: Go; indent-tabs-mode: t -*- | ||
| /* | ||
| - * Copyright (C) 2016 Canonical Ltd | ||
| + * Copyright (C) 2017 Canonical Ltd |
jdstrand
requested changes
Aug 2, 2017
This is very much on the right track, thanks! Please make the requested changes.
Curious on the testing performed-- I know you updated the testsuite but did you blackbox test by connecting these plugs and seeing if you could access the devices?
| +KERNEL=="pcm[CD0-9cp]*", NAME="snd/%%k", TAG+="%[1]s" | ||
| +KERNEL=="midiC[D0-9]*", NAME="snd/%%k", TAG+="%[1]s" | ||
| +KERNEL=="timer", NAME="snd/%%k", TAG+="%[1]s" | ||
| +KERNEL=="seq", NAME="snd/%%k", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
Where did you get this list? I don't think it is quite right be looking at my system and reading http://www.reactivated.net/writing_udev_rules.html#strmatch. Also, I don't think we need 'NAME' here since we are only tagging kernel devices and not trying to rename them (this is true everywhere you use NAME)-- did you add NAME for a specific reason?
I think you want this instead:
KERNEL=="controlC[0-9]*", TAG+="%[1]s"
KERNEL=="hwC[0-9]*D[0-9]*", TAG+="%[1]s"
KERNEL=="pcmC[0-9]*D[0-9]*[cp]", TAG+="%[1]s"
KERNEL=="midiC[0-9]*D[0-9]*", TAG+="%[1]s"
KERNEL=="timer", TAG+="%[1]s"
KERNEL=="seq", TAG+="%[1]s"
jdstrand
Aug 2, 2017
Contributor
Not to mention, I feel like the list may be incomplete. I see in /lib/udev/rules.d references to card*. I think at least this should be added:
SUBSYSTEM=="sound", KERNEL=="card[0-9]*", TAG+="%[1]s"
adglkh
Aug 3, 2017
Contributor
Adding the name here ensures that the sound device node appears exclusively in the /dev/snd directory where they are created in my system and also it meant to be consistent with /dev/snd/* in apparmor policy for alsa interface. Removing the name results in sound devices are created under /dev directory by default. But I couldn't find them there(/dev) in my system.
Basically, it's harmless to have 'NAME' here for each device. I need to confirm this at this point before I proceed.
SUBSYSTEM=="sound", KERNEL=="card[0-9]*", TAG+="%[1]s"
Yes, I saw it. Thanks for the mention.
jdstrand
Aug 3, 2017
Contributor
Well, the system should already have rules for putting devices in /dev/snd. Your rules are only about tagging the devices. AIUI the NAME field, it does affect where things are put so I didn't want to override what the system is already providing so suggested that NAME be removed.
Are you saying that if you omit NAME, when you connect the interface you now see /dev/pcm..., etc? If that is the case, we should look at why that is happening-- we only want to add a tag, not change existing rules.
adglkh
Aug 4, 2017
Contributor
Okay, got your point.
Let's remove NAME key for each rule of the interfaces.
I'll also give it a try on snap to check if it works for me with the fine-tuned udev rules.
Thanks.
| +KERNEL=="midiC[D0-9]*", NAME="snd/%k", TAG+="snap_other_app" | ||
| +KERNEL=="timer", NAME="snd/%k", TAG+="snap_other_app" | ||
| +KERNEL=="seq", NAME="snd/%k", TAG+="snap_other_app" | ||
| +` |
jdstrand
Aug 2, 2017
Contributor
It's a little weird that the expectedSnippet declaration is so far from its use. Can you move it after the apparmor tests and before the udev tests? This is true for other _test.go files as well.
| +# | ||
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +SUBSYSTEM=="bluetooth", KERNEL=="hci[0-9]*", TAG+="%s" |
jdstrand
Aug 2, 2017
Contributor
hci* are virtual devices-- do virtual devices need to be added to the device cgroup?. Also, bluetooth-control does have an apparmor access for /dev/vhci but there is no udev rule for it.
| +# | ||
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +SUBSYSTEM=="net", KERNEL=="bdev", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
I thought this was going to be (to match the apparmor /dev access):
SUBSYSTEM=="net", KERNEL=="linux-user-bde", TAG+="%[1]s"
SUBSYSTEM=="net", KERNEL=="linux-kernel-bde", TAG+="%[1]s"
SUBSYSTEM=="net", KERNEL=="linux-bcm-knet", TAG+="%[1]s"
where did you get your rule?
adglkh
Aug 3, 2017
Contributor
Here is the udev rule from upstream,
https://git.openswitch.net/cgit/openswitch/ops-build/commit/?id=c0e324d0e76e9464f115434cce74301b5794ff61
I'm afraid it doesn't work that way if we use kernel module name rather than the 'bdev' (bcm device) in this case.
jdstrand
Aug 3, 2017
Contributor
So long as we are using base_dev_name=bdev in the module loading, I guess what you had before would work. Where do we guarantee that is happening?
If using 'bdev' instead, can you add a comment above your rule?
adglkh
Aug 4, 2017
Contributor
Yes, basically, this interface was added since it's needed by a customer project.
I compared the rule with what was being added into upstream and found the difference here.
I'll do a further investigation on these two rules and confirm the final behavior on real device and will add the upstream link above the rule if it's the one we needed.
adglkh
Aug 7, 2017
Contributor
@jdstrand, I took a closer look today on a machine a kernel built for openswitch.
A udev rule(/etc/udev/rules.d/60-bcm-driver.rules) executes external comment to creates three character device files(via mknod) by using loadable kernel modules, However, I am not able to query the information for all three character devices on the machine.
http://paste.ubuntu.com/25262959/
I found some hints after exporting the content of the udev database (keyword: "linux-kernel-bde" and "bcm0")
http://paste.ubuntu.com/25262850/
Then query all information for the first matched device
http://paste.ubuntu.com/25262846/
Meanwhile, there's another 'bcm0' device can be found in sysfs (the second matched device)
http://paste.ubuntu.com/25262841/
Based on these findings, the udev tagging rule for this interface would be
SUBSYSTEM=="pci", DRIVER=="linux-kernel-bde", TAG+="%[1]s"
SUBSYSTEM=="net", KERNEL=="bcm[0-9]*", TAG+="%[1]s"
Also apparmor policy is needed to update somehow by adding a few lines, here are what I have in mind.
/sys/devices/pci[0-9]*/**/config r,
/sys/devices/pci[0-9]*/**/{,subsystem_}device r,
/sys/devices/pci[0-9]*/**/{,subsystem_}vendor r,
/sys/bus/pci/devices/** r,
/run/udev/data/+pci:[0-9]* r,
jdstrand
Aug 7, 2017
Contributor
+1 on the udev changes. The apparmor policy is too broad. Can you give the specific denials the prompted each rule?
| +# /dev/mapper/docker* rw, | ||
| +# | ||
| +# dmsetup tool is required to apply the following udev rule. However it looks like we don't have dmsetup pre-installed on core. | ||
| +KERNEL=="dm-[0-9]*", PROGRAM="/sbin/dmsetup info -c --noopencount --noheadings -o name -j %%M -m %%m", NAME="%%k", SYMLINK+="mapper/%%c", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
I don't think we want to have udev rules for docker-supprort since docker can be used to add devices to a container. If we add udev rules, the only devices it could add would be those here. Perhaps it makes sense to document in the interface that we are intentionally not creating udev rules.
adglkh
Aug 3, 2017
Contributor
Yes, docker supports to add a rule to the cgroup allowed devices list.
I'll drop udev rules for docker-support interface in this case and document the reason.
Thanks for the mention.
| +# | ||
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +KERNEL=="tty", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
/dev/tty is already added by defaults (see cmd/snap-confine/udev-support.c)
| +KERNEL=="mice", NAME="input/%%k", TAG+="%[1]s" | ||
| +KERNEL=="mouse*", NAME="input/%%k", TAG+="%[1]s" | ||
| +KERNEL=="event*", NAME="input/%%k", TAG+="%[1]s" | ||
| +KERNEL=="js*", NAME="input/%%k", TAG+="%[1]s" |
adglkh
Aug 3, 2017
Contributor
Yes, I should remove it to avoid overlapping each other.
Same for /dev/ttyS* in modem_manager.go
| +KERNEL=="mouse*", NAME="input/%%k", TAG+="%[1]s" | ||
| +KERNEL=="event*", NAME="input/%%k", TAG+="%[1]s" | ||
| +KERNEL=="js*", NAME="input/%%k", TAG+="%[1]s" | ||
| +KERNEL=="ts*", NAME="input/%%k", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
Where did you see /dev/input/ts*? Also, instead of mouse*, event* and ts*, I think we want mouse[0-9]*, event[0-9]* and ts[0-9]*. Also, you should drop 'NAME=' (see above).
adglkh
Aug 4, 2017
Contributor
RE: /dev/input/ts*
1.https://kernel.googlesource.com/pub/scm/linux/hotplug/udev/+/127/rules/rules.d/50-udev-default.rules#27
2.https://github.com/kergoth/tslib
It's a udev rule for the touchscreen device.
| + spec.AddSnippet(fmt.Sprintf(mirPermanentSlotUdev, tag)) | ||
| + } | ||
| + return nil | ||
| +} |
jdstrand
Aug 2, 2017
Contributor
Would it make sense to move this to common.go like you did UDevConnectedPlug?
| @@ -200,6 +201,8 @@ const modemManagerPermanentSlotUDev = ` | ||
| # Concatenation of all ModemManager udev rules | ||
| # do not edit this file, it will be overwritten on update | ||
| +KERNEL=="tty[A-Z]*[0-9]|cdc-wdm[0-9]*" TAG+="%s" |
jdstrand
Aug 2, 2017
Contributor
I think you meant to remove this since you are adding per-command lines via modemManagerPermanentSlotUDevTag.
| +# | ||
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +KERNEL=="tty[A-Z]*[0-9]|cdc-wdm[0-9]*", TAG+="%s" |
jdstrand
Aug 2, 2017
Contributor
This includes /dev/ttyS* which might be what you want. Can you comment? If not, this should work:
# omit ttyS* since that is covered by the serial-port interface
KERNEL=="tty[A-RT-Z]*[0-9]|cdc-wdm[0-9]*" TAG+="%s"
adglkh
Aug 3, 2017
Contributor
Aha, I didn't notice we already have /dev/ttyS* in serial-port interface.
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +KERNEL=="rfkill", TAG+="%[1]s" | ||
| +KERNEL=="tap*", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
According to https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/devices.txt, I think we should use:
KERNEL=="tap[0-9]*", TAG+="%[1]s"
| + | ||
| +KERNEL=="rfkill", TAG+="%[1]s" | ||
| +KERNEL=="tap*", TAG+="%[1]s" | ||
| +KERNEL=="tun[0-9]*", NAME="net/%%k", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
We need this here (use of /dev/net/tun creates /dev/tun* devices):
KERNEL=="tun", TAG+="%[1]s"
KERNEL=="tun[0-9]*", TAG+="%[1]s"
| +# | ||
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +KERNEL=="tty[A-Z]*[0-9]|cdc-wdm[0-9]*", TAG+="%[1]s" |
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +KERNEL=="tty[A-Z]*[0-9]|cdc-wdm[0-9]*", TAG+="%[1]s" | ||
| +KERNEL=="tun[0-9]*", NAME="net/%%k", TAG+="%[1]s" |
| +KERNEL=="tun[0-9]*", NAME="net/%%k", TAG+="%[1]s" | ||
| +KERNEL=="dsp", TAG+="%[1]s" | ||
| +KERNEL=="ttyLTM[0-9]", SYMLINK+="modem%%e", TAG+="%[1]s" | ||
| +KERNEL=="ttyUSB[0-9]", SYMLINK+="modem%%e", TAG+="%[1]s" |
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +KERNEL=="card[0-9]*", NAME="dri/card%%n", TAG+="%[1]s" | ||
| +KERNEL=="nvidia*|nvidiactl*", NAME="%%k", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
Drop 'NAME=' here and you missed /dev/vchiq.This should be:
SUBSYSTEM="drm", KERNEL=="card[0-9]*", TAG+="%[1]s"
KERNEL=="nvidia*", TAG+="%[1]s"
KERNEL=="vchiq", TAG+="%[1]s"
Since the apparmor policy has a redundancy too, can you update it to remove /dev/nvidiactl rw, and /dev/nvidia-modeset rw, since /dev/nvidia* rw, covers all of them?
adglkh
Aug 3, 2017
•
Contributor
Sure.
One quick question: Is vchiq kept for bcm device(GPU) on PI?
Thanks.
| +# | ||
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +KERNEL=="sr[0-9]*", NAME="%%k", SYMLINK+="scd%%n", TAG+="%s" |
jdstrand
Aug 2, 2017
Contributor
We can drop NAME and SYMLINK. /dev/scd* aren't always symlinks, so adjust to be:
KERNEL=="sr[0-9]*", TAG+="%[1]s"
KERNEL=="scd[0-9]*", TAG+="%[1]s"
| + | ||
| +func (s *OpticalDriveInterfaceSuite) TestInterfaces(c *C) { | ||
| + c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface) | ||
| +} |
| - return true | ||
| -} | ||
| +KERNEL=="ppp", TAG+="%[1]s" | ||
| +KERNEL=="tty[0-9]*", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
The apparmor rule was /dev/tty[^0-9]* rw,, so this should be:
KERNEL=="tty[A-Z]*", TAG+="%[1]s"
| +# Do not edit this file, it will be overwritten on updates | ||
| +KERNEL=="pcm[CD0-9cp]*", NAME="snd/%%k", TAG+="%[1]s" | ||
| +KERNEL=="controlC[0-9]*", NAME="snd/%%k", TAG+="%[1]s" | ||
| +KERNEL=="timer", NAME="snd/%%k", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
Like above, drop NAME and update the globs to be:
KERNEL=="controlC[0-9]*", TAG+="%[1]s"
KERNEL=="pcmC[0-9]*D[0-9]*[cp]", TAG+="%[1]s"
KERNEL=="timer", TAG+="%[1]s"
| - // Allow what is allowed in the declarations | ||
| - return true | ||
| -} | ||
| +KERNEL=="/dev/rtc0", TAG+="%s" |
| +# | ||
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +KERNEL=="tpm*", TAG+="%s" |
| +# Do not edit this file, it will be overwritten on updates | ||
| + | ||
| +KERNEL=="sr*|md*|fd*|sd*|mmcblk[0-9]|mspblk[0-9]", TAG+="%[1]s" | ||
| +SUBSYSTEMS=="usb", TAG+="%[1]s" |
jdstrand
Aug 2, 2017
Contributor
I know we're missing vd*. I think perhaps change this to:
SUBSYSTEM=="block", TAG+="%[1]s"
KERNEL=="fd[0-9]*, TAG+="%[1]s"
# This tags all USB devices, so we'll use AppArmor to mediate specific access (eg, /dev/sd* and /dev/mmcblk*)
SUBSYSTEM=="usb", TAG+="%[1]s"
Can you update the apparmor policy to have this:
/dev/vd* r,
adglkh
Aug 3, 2017
Contributor
My concerns on this line were that it probably opens unnecessary holes in the confinement system since we grant people permission accessing all USB devices. However I forget, on the other hand, we could enforce AppArmor profile constraints for the confinement escape. I guess this strategy applies to raw_usb, broadcom_asic_control too. Thanks for your comments above
adglkh
Aug 4, 2017
Contributor
@jdstrand I double-checked here
fd[0-9]* would be covered by SUBSYSTEM=="block", do we really need to keep fd[0-9]* in the udev rule for udisk2 interface?
jdstrand
Aug 4, 2017
Contributor
I would be fine to remove the fd lines-- I was looking at the udev rules and saw it handled floppy a little differently, so put it. Really, it doesn't matter-- the apparmor policy currently only allows /dev/sd* and /dev/mmcblk* (and if you added it, /dev/vd*). I think you are right to just use block and usb subsystems and then we'll use apparmor globbing for which to allow.
| + | ||
| +func (s *CameraInterfaceSuite) TestInterfaces(c *C) { | ||
| + c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface) | ||
| +} |
|
Thanks for a detailed review. I have a bunch of simple apps with individual and multiple interfaces combinations declared in its yaml file for black-box testing(udev tagging verification). I was also thinking if it's good timing to update spread test of snap-confine. We moved snap-confine into snapd, but it looks like we didn't update the doc and scripts accordingly(I encountered the folder&file path issue during running spread-test ). Also in order to run spread test of snap-confine, we're still relying on https://git.launchpad.net/snap-confine to build the package. It failed since one dependency(xfslibs-dev) we recently added is missing in control file of snap-confine repo on lp. Probably we need a separated PR to fix it. |
jdstrand
deleted a comment from
adglkh
Aug 3, 2017
|
This branch is on my TODO list but it's somewhat pushed back given how huge it is. I'll try to review it today though. |
zyga
reviewed
Aug 4, 2017
This is a pretty big PR and I'd like to de-compose it somewhat. Here's what I propose:
- create a new PR with the new common udev function and (perhaps separate) simplification of existing interfaces to let them become common
- tweaks and updates to tests (I'm trying to unify how those are done lately)
- per-interface PRs that do udev tagging. This seems painful but I think it is much saner than iterating on one huge PR that touches a thousand lines in half of the interface files.
If you don't disagree I'll start chopping this into pieces and iterating on all the elements.
| @@ -142,3 +145,13 @@ func (iface *commonInterface) SecCompConnectedPlug(spec *seccomp.Specification, | ||
| } | ||
| return nil | ||
| } | ||
| + | ||
| +func (iface *commonInterface) UDevConnectedPlug(spec *udev.Specification, plug *interfaces.Plug, plugAttrs map[string]interface{}, slot *interfaces.Slot, slotAttrs map[string]interface{}) error { |
zyga
Aug 4, 2017
Contributor
Thank you for doing this. I wanted to add something like this for a long time lately
adglkh
and others
added some commits
Aug 4, 2017
|
Yay, the PR shrank by a few lines. I'll iterate on the remaining changes and try to get them merged to master separately so that this PR can focus just on actual udev changes. |
|
Ooops, Looks like sth went wrong with the merging. |
adglkh
added some commits
Aug 15, 2017
zyga
reviewed
Aug 16, 2017
I made a few remarks. I don't mind merging this if @jdstrand agrees. I highlighted some parts that could land immediately in separate PRs and one thing that is not related to udev.
| -// TODO: we are not doing this due to the bug and we'll be reintroducing | ||
| -// the udev tagging soon. | ||
| -// const framebufferUDevConnectedPlug = `KERNEL=="fb[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"` | ||
| +const framebufferConnectedPlugUDev = `KERNEL=="fb[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"` |
| @@ -157,25 +157,18 @@ func (s *I2cInterfaceSuite) TestSanitizeBadGadgetSnapSlot(c *C) { | ||
| c.Assert(s.testUDevBadValue7.Sanitize(s.iface), ErrorMatches, "i2c slot must have a path attribute") | ||
| } | ||
| -func (s *I2cInterfaceSuite) TestConnectedPlugUDevSnippets(c *C) { |
| } | ||
| -func (s *I2cInterfaceSuite) TestConnectedPlugAppArmorSnippets(c *C) { |
| @@ -154,13 +154,10 @@ func (s *IioInterfaceSuite) TestSanitizeBadGadgetSnapSlot(c *C) { | ||
| } | ||
| func (s *IioInterfaceSuite) TestConnectedPlugUDevSnippets(c *C) { |
| @@ -38,7 +38,7 @@ const joystickConnectedPlugAppArmor = ` | ||
| /run/udev/data/c13:{[0-9],[12][0-9],3[01]} r, | ||
| ` | ||
| -//const joystickConnectedPlugUDev = `KERNEL=="js[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"` |
| @@ -76,7 +77,7 @@ func (s *KernelModuleControlInterfaceSuite) TestSanitizePlug(c *C) { | ||
| c.Assert(s.plug.Sanitize(s.iface), IsNil) | ||
| } | ||
| -func (s *KernelModuleControlInterfaceSuite) TestUsedSecuritySystems(c *C) { | ||
| +func (s *KernelModuleControlInterfaceSuite) TestAppArmorSpec(c *C) { |
| + udevRule := modemManagerPermanentSlotUDev | ||
| + for appName := range slot.Apps { | ||
| + tag := udevSnapSecurityName(slot.Snap.Name(), appName) | ||
| + udevRule += fmt.Sprintf(modemManagerPermanentSlotUDevTag, tag) |
| +func (iface *networkManagerInterface) UDevPermanentSlot(spec *udev.Specification, slot *interfaces.Slot) error { | ||
| + for appName := range slot.Apps { | ||
| + tag := udevSnapSecurityName(slot.Snap.Name(), appName) | ||
| + spec.AddSnippet(fmt.Sprintf(networkManagerPermanentSlotUdev, tag)) |
| + udevRule := ofonoPermanentSlotUDev | ||
| + for appName := range slot.Apps { | ||
| + tag := udevSnapSecurityName(slot.Snap.Name(), appName) | ||
| + udevRule += fmt.Sprintf(ofonoPermanentSlotUDevTag, tag) |
zyga
Aug 16, 2017
Contributor
I'd love the same replacement logic that we use elsewhere simply because this will lessen the friction to unify everything at some point in the future.
| @@ -79,40 +80,14 @@ func (s *OpenglInterfaceSuite) TestAppArmorSpec(c *C) { | ||
| spec := &apparmor.Specification{} | ||
| c.Assert(spec.AddConnectedPlug(s.iface, s.plug, nil, s.slot, nil), IsNil) | ||
| c.Assert(spec.SecurityTags(), DeepEquals, []string{"snap.consumer.app"}) | ||
| - c.Assert(spec.SnippetForTag("snap.consumer.app"), Equals, ` |
| +func (iface *pulseAudioInterface) UDevPermanentSlot(spec *udev.Specification, slot *interfaces.Slot) error { | ||
| + for appName := range slot.Apps { | ||
| + tag := udevSnapSecurityName(slot.Snap.Name(), appName) | ||
| + spec.AddSnippet(fmt.Sprintf(pulseaudioPermanentSlotUdev, tag)) |
| @@ -1,7 +1,7 @@ | ||
| // -*- Mode: Go; indent-tabs-mode: t -*- | ||
| /* | ||
| - * Copyright (C) 2016 Canonical Ltd |
| @@ -102,6 +102,7 @@ umount /{,run/}media/**, | ||
| # give raw read access to the system disks and therefore the entire system. | ||
| /dev/sd* r, | ||
| /dev/mmcblk* r, | ||
| +/dev/vd* r, |
zyga
Aug 16, 2017
Contributor
This is not related to the change (not that I dislike it but it confuses the premise of the PR)
| @@ -45,44 +37,17 @@ const uhidConnectedPlugAppArmor = ` | ||
| /dev/uhid rw, | ||
| ` | ||
| -type uhidInterface struct{} |
|
I just wanna keep the same code patterns in test cases for all interfaces I worked on and squeeze something unrelated to udev tagging changes in this PR. |
added a commit
to adglkh/snapd
that referenced
this pull request
Aug 16, 2017
adglkh
referenced this pull request
Aug 16, 2017
Merged
interfaces: convert uhid to common interface and test cases improvement for time_control and opengl #3745
adglkh
added some commits
Aug 16, 2017
|
@jdstrand can you please re-review this PR? Garry worked on making the diff nice and small by merging other branches into master. |
zyga
added this to the 2.28 milestone
Aug 17, 2017
|
Yes. I would've done it sooner but @adglkh said he had more to do. I see new commits since then, so I'll take a look today. |
jdstrand
requested changes
Aug 17, 2017
This is really close; thanks for all your hard work on this. In addition to the other inline comments, please adjust TAG+="###SLOT_SECURITY_TAGS###" to be TAG+="###CONNECTED_SECURITY_TAGS###". It seems these crept in some previous commits, but lets make sure at least the things we are changing in this PR are correct. You'll want to also change interfaces/builtin/common.go
| @@ -1,7 +1,7 @@ | ||
| // -*- Mode: Go; indent-tabs-mode: t -*- | ||
| /* | ||
| - * Copyright (C) 2016 Canonical Ltd | ||
| + * Copyright (C) 2016-2017 Canonical Ltd |
jdstrand
Aug 17, 2017
Contributor
You changed the copyright in bluetooth_control_test.go, but forgot to update it and bluetooth_control.go for /dev/vhci, which is included in the apparmor policy. Can you add that?
adglkh
Aug 18, 2017
•
Contributor
/dev/vhci is just a node that vhci driver created. I am not able to find it in udev database even if it exists. http://paste.ubuntu.com/25336192/
If we add udev rules, the devices we want to tag are the virtual devices.
`SUBSYSTEM=="bluetooth", KERNEL=="hci[0-9]*", TAG+="%s"
Yes, "%s" will be changed to ###CONNECTED_SECURITY_TAGS###
jdstrand
Aug 18, 2017
•
Contributor
Oh that is interesting, but I really like your idea of SUBSYSTEM bluetooth. How about just treat this like raw-usb and do:
SUBSYSTEM=="bluetooth", TAG+="%s
The 'hci' devices are virtual devices and not yet mediated by AppArmor or devices that need to be added to the device cgroup. However, tagging all bluetooth devices helps future-proof a bit in case /dev/vhci ends up showing up in udev or other bluetooth devices show up in /dev.
| @@ -192,6 +193,8 @@ const bluezPermanentSlotDBus = ` | ||
| </policy> | ||
| ` | ||
| +const bluezConnectedPlugUDev = `KERNEL=="rfkill", TAG+="###SLOT_SECURITY_TAGS###"` |
jdstrand
Aug 17, 2017
Contributor
The variable name is bluezConnectedPlugUDev but the TAG is ###SLOT_SECURITY_TAGS###, which is not quite right. With apparmor policy there is plug side and slot side policy, but with udev tagging, there is only the tag of what is being connected. I suggest changing to ###CONNECTED_SECURITY_TAGS###
| +/sys/devices/pci[0-9]*/0000:00:1c.0/{,subsystem_}vendor r, | ||
| + | ||
| +/sys/bus/pci/devices/0000:00:1c.0/** r, | ||
| +/run/udev/data/+pci:0000:00:1c.0 r, |
jdstrand
Aug 17, 2017
Contributor
This doesn't seem right since I suspect that the devices might show up in other places than /sys/devices/pci0000:00/0000:00:1c.0. For example, I don't have these modules loaded on my laptop, but I do have these paths.
Until https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1570860/comments/1 is implemented, we probably need to use broader glob rules like:
/sys/devices/pci[0-9]*/**/config r,
/sys/devices/pci[0-9]*/**/{,subsystem_}device r,
/sys/devices/pci[0-9]*/**/{,subsystem_}vendor r,
/sys/bus/pci/devices/ r,
/run/udev/data/+pci:[0-9]* r,
Note, I changed the /sys/bus/pci/devices rule because it should be filled with symlinks, not actual files, and apparmor resolves symlinks.
adglkh
Aug 17, 2017
Contributor
Ah, right. There was another common detail I didn't take into account.
Using broader glob rules is a good fit, at least for now.
I take a note here.
RE: /sys/bus/pci/devices rule
I'd expect we need the same change for opengl interface.
Thanks for your explanation!
| +# The second rule for matched device http://paste.ubuntu.com/25262841/ | ||
| + | ||
| +KERNEL=="0000:01:00.0", SUBSYSTEM=="pci", DRIVER=="linux-kernel-bde", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +SUBSYSTEM=="net", KERNEL=="bcm[0-9]*", TAG+="###SLOT_SECURITY_TAGS###" |
jdstrand
Aug 17, 2017
Contributor
I'm surprised you can use KERNEL=="0000:01:00.0" here, but if it works, +1.
Note, I don't think we should have pastebins in the comments since I think they go away after awhile. Perhaps just mention the importants bits from the pastes (possibly with examples entries instead of all of them).
| @@ -42,6 +42,8 @@ const cameraConnectedPlugAppArmor = ` | ||
| /sys/devices/pci**/usb*/**/video4linux/** r, | ||
| ` | ||
| +const cameraConnectedPlugUDev = `KERNEL=="video[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"` |
| -// TODO: we are not doing this due to the bug and we'll be reintroducing | ||
| -// the udev tagging soon. | ||
| -// const framebufferUDevConnectedPlug = `KERNEL=="fb[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"` | ||
| +const framebufferConnectedPlugUDev = `KERNEL=="fb[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"` |
| @@ -83,8 +83,9 @@ deny /etc/fuse.conf r, | ||
| #/{,usr/}bin/fusermount ixr, | ||
| ` | ||
| +const fuseSupportConnectedPlugUDev = `KERNEL=="fuse", TAG+="###SLOT_SECURITY_TAGS###"` |
| @@ -38,7 +38,7 @@ const joystickConnectedPlugAppArmor = ` | ||
| /run/udev/data/c13:{[0-9],[12][0-9],3[01]} r, | ||
| ` | ||
| -//const joystickConnectedPlugUDev = `KERNEL=="js[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"` | ||
| +const joystickConnectedPlugUDev = `KERNEL=="js[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"` |
| @@ -1187,6 +1188,11 @@ KERNEL=="cdc-wdm*", SUBSYSTEM=="usbmisc", ENV{ID_MM_CANDIDATE}="1" | ||
| LABEL="mm_candidate_end" | ||
| ` | ||
| +const modemManagerPermanentSlotUDevTag = ` | ||
| +# omit ttyS* since that is covered by the serial-port interface | ||
| +KERNEL=="tty[A-RT-Z]*[0-9]|cdc-wdm[0-9]*", TAG+="%s" |
jdstrand
Aug 17, 2017
Contributor
I think this should be:
KERNEL=="tty[A-RT-Z]*[0-9]*|cdc-wdm[0-9]*", TAG+="%s"
(note the '*' after tty[A-RT-Z]*[0-9]).
That said, in thinking about this more, the modem-manager interface apparmor policy currently allows /dev/ttyS[0-9]* so in retrospect, I think we should use this so as not to break existing snaps that don't plugs serial-port (not to mention, serial-port only shows up with configured gadgets so there would be no way to have modem-manager use /dev/ttyS*, which would be a regression):
KERNEL=="tty[A-Z]*[0-9]*|cdc-wdm[0-9]*", TAG+="%s"
| +KERNEL=="rfkill", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="tap[0-9]*", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="tun", TAG+="###SLOT_SECURITY_TAGS###", | ||
| +KERNEL=="tun[0-9]*", TAG+="###SLOT_SECURITY_TAGS###" |
| @@ -407,6 +408,8 @@ const networkManagerPermanentSlotDBus = ` | ||
| <limit name="max_match_rules_per_connection">2048</limit> | ||
| ` | ||
| +const networkManagerPermanentSlotUdev = `KERNEL=="rfkill", TAG+="###SLOT_SECURITY_TAGS###"` |
| @@ -288,6 +288,15 @@ ATTRS{idVendor}=="1c9e", ATTRS{idProduct}=="9605", ENV{ID_USB_INTERFACE_NUM}=="0 | ||
| LABEL="ofono_speedup_end" | ||
| ` | ||
| +const ofonoPermanentSlotUDevTag = ` | ||
| +KERNEL=="tty[A-RT-Z]*[0-9]|cdc-wdm[0-9]*", TAG+="###SLOT_SECURITY_TAGS###" |
jdstrand
Aug 17, 2017
Contributor
Same here as with modem-manager:
KERNEL=="tty[A-Z]*[0-9]*|cdc-wdm[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"
| +KERNEL=="tun[0-9]*", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="dsp", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="ttyLTM[0-9]", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="ttyUSB[0-9]", TAG+="###SLOT_SECURITY_TAGS###" |
jdstrand
Aug 17, 2017
Contributor
These two ttys are covered by the first rule.
Also, I think we need (for other apparmor accesses):
KERNEL=="modem[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"
KERNEL=="chnlat[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"
KERNEL=="rild[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"
Also, s/###SLOT_SECURITY_TAGS###/###CONNECTED_SECURITY_TAGS###/'
adglkh
Aug 17, 2017
Contributor
I didn't find above three udev rules after digging around.
RE: KERNEL=="modem[0-9]*"
Basically, Linux modem drivers set up the modem device /dev/modem as a symbolic link to the actual device to /dev/ttyS*. So first entry would cover this case.
And /dev/socket/rild is just a socket created by rild daemon when it runs during system boot up. See here
https://stackoverflow.com/questions/11111067/how-does-modem-code-talk-to-android-code/11111953#11111953
I suspect if it's an actual device node we can find in udev database. Same for chnlat.
So I doubt if they're really needed putting here to tag device node which does not actually exist in system.
jdstrand
Aug 17, 2017
Contributor
If modem is always a symlink, then that's fine (we could remove the apparmor rule then too since apparmor resolves symlinks).
jdstrand
Aug 17, 2017
Contributor
If rild and chnlat are actually a sockets, then we don't need a udev rule. Can you add a comment above ofonoPermanentSlotUDevTag that we intetionally skipped modem, rild and chnlat, and why?
| +const openglConnectedPlugUDev = ` | ||
| +SUBSYSTEM="drm", KERNEL=="card[0-9]*", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="nvidia*", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="vchiq", TAG+="###SLOT_SECURITY_TAGS###" |
| @@ -36,13 +36,19 @@ const opticalDriveConnectedPlugAppArmor = ` | ||
| /run/udev/data/b11:[0-9]* r, | ||
| ` | ||
| +const opticalDriveConnectedPlugUDev = ` | ||
| +KERNEL=="sr[0-9]*", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="scd[0-9]*", TAG+="###SLOT_SECURITY_TAGS###" |
| @@ -55,6 +55,11 @@ var pppConnectedPlugKmod = []string{ | ||
| "ppp_generic", | ||
| } | ||
| +const pppConnectedPlugUDev = ` | ||
| +KERNEL=="ppp", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="tty[A-Z]*", TAG+="###SLOT_SECURITY_TAGS###" |
jdstrand
Aug 17, 2017
Contributor
We're using this elsewhere:
KERNEL=="tty[A-Z]*[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"
Also, s/###SLOT_SECURITY_TAGS###/###CONNECTED_SECURITY_TAGS###/
| +const pulseaudioPermanentSlotUdev = ` | ||
| +KERNEL=="controlC[0-9]*", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="pcmC[0-9]*D[0-9]*[cp]", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="timer", TAG+="###SLOT_SECURITY_TAGS###" |
| @@ -45,6 +45,8 @@ const rawusbConnectedPlugAppArmor = ` | ||
| /run/udev/data/+usb:* r, | ||
| ` | ||
| +const rawusbConnectedPlugUDev = `SUBSYSTEMS=="usb", TAG+="###SLOT_SECURITY_TAGS###"` |
| @@ -92,7 +92,7 @@ capability sys_time, | ||
| /sbin/hwclock ixr, | ||
| ` | ||
| -const timeControlConnectedPlugUDev = `KERNEL=="/dev/rtc0", TAG+="###SLOT_SECURITY_TAGS###"` | ||
| +const timeControlConnectedPlugUDev = `SUBSYSTEM=="rtc", TAG+="###SLOT_SECURITY_TAGS###"` |
| @@ -35,6 +35,8 @@ const tpmConnectedPlugAppArmor = ` | ||
| /dev/tpm0 rw, | ||
| ` | ||
| +const tpmConnectedPlugUDev = `KERNEL=="tpm[0-9]*", TAG+="###SLOT_SECURITY_TAGS###"` |
| +const udisks2PermanentSlotUDevTag = ` | ||
| +SUBSYSTEM=="block", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +# This tags all USB devices, so we'll use AppArmor to mediate specific access (eg, /dev/sd* and /dev/mmcblk*) | ||
| +SUBSYSTEM=="usb", TAG+="###SLOT_SECURITY_TAGS###" |
jdstrand
approved these changes
Aug 18, 2017
+1. Thanks for working through this large task! This is going to really help people.
Just a request to add one comment and then one question that I'll leave to your discretion to fix.
| @@ -38,12 +38,18 @@ const broadcomAsicControlConnectedPlugAppArmor = ` | ||
| /dev/linux-user-bde rw, | ||
| /dev/linux-kernel-bde rw, | ||
| /dev/linux-bcm-knet rw, | ||
| + | ||
| +/sys/devices/pci[0-9]*/**/config r, |
jdstrand
Aug 18, 2017
Contributor
Can you add a comment here:
# These are broader than they needs to be, but until we query udev
# for specific devices, use a broader glob
| -KERNEL=="linux-user-bde", TAG+="###SLOT_SECURITY_TAGS###" | ||
| -KERNEL=="linux-kernel-bde", TAG+="###SLOT_SECURITY_TAGS###" | ||
| -KERNEL=="linux-bcm-knet", TAG+="###SLOT_SECURITY_TAGS###" | ||
| +KERNEL=="0000:01:00.0", SUBSYSTEM=="pci", DRIVER=="linux-kernel-bde", TAG+="###CONNECTED_SECURITY_TAGS###" |
jdstrand
Aug 18, 2017
Contributor
Is KERNEL=="0000:01:00.0" correct (ie, is it too narrow?). If so, perhaps just:
SUBSYSTEM=="pci", DRIVER=="linux-kernel-bde", TAG+="###CONNECTED_SECURITY_TAGS###"
adglkh
Aug 18, 2017
Contributor
The above rules address my concerns as well.
To some extent, IMHO, The following rule is probably good enough in this case
DRIVER=="linux-kernel-bde", TAG+="###CONNECTED_SECURITY_TAGS###"
Let's finalise with yours proposal
SUBSYSTEM=="pci", DRIVER=="linux-kernel-bde", TAG+="###CONNECTED_SECURITY_TAGS###"
niemeyer
changed the title from
Using udev tagging for snap interfaces
to
interfaces/builtin: use udev tagging more broadly
Aug 23, 2017
| @@ -38,12 +38,20 @@ const broadcomAsicControlConnectedPlugAppArmor = ` | ||
| /dev/linux-user-bde rw, | ||
| /dev/linux-kernel-bde rw, | ||
| /dev/linux-bcm-knet rw, | ||
| + | ||
| +# These are broader than they needs to be, but until we query udev | ||
| +# for specific devices, use a broader glob |
niemeyer
Aug 23, 2017
Contributor
Indeed, that looks way too broad. In fact, a bit too broad to be right. Not sure it makes sense to turn the "broadcoam-asic" interface in a sort of "read about every single PCI device in the system".
@jdstrand Note that we won't be able to change that in the future without the potential of breaking clients unknowingly.
What's the plan here?
adglkh
Aug 24, 2017
Contributor
I think it's related to hardware assignment. We have a bug on launchpad tracking on this. Not sure where are we with that.
@jdstrand Could you share the updates and plan here?
Thanks
jdstrand
Aug 24, 2017
Contributor
@niemeyer, @adglkh - they are necessarily broad because in PR review it was found there was nothing in the /sys/devices path alone that made it 'broadcom-asic'. I believe it is technically possible for snapd to interrogate the system via udev to get the precise /sys/devices and /run/udev/data paths for the device (see #1226 (comment) for back of the napkin idea), but this work is neither prioritized nor assigned. As a result, this interface along with existing opengl and camera interfaces use rules that are broader than they should be (but we comment in the policy in camera and opengl about the leak). While the accesses in question do constitute an information leak, they are not terribly significant (which is why the work is not prioritized/assigned) and in the 'future work' bucket.
I think the plan should be:
- continue with the access as written since without it, things break
- add a comment that this is an information leak (see opengl.go)
- at some future time, implement the udev querying in snapd and have new interfaces in series 16 use this
- in some future iteration of snappy which is generating different policy (eg, something not 'series 16'), migrate existing interfaces that use the broad globs to using only the outputs of udev querying
| @@ -51,7 +51,7 @@ const openglConnectedPlugAppArmor = ` | ||
| # FIXME: this is an information leak and snapd should instead query udev for | ||
| # the specific accesses associated with the above devices. | ||
| - /sys/bus/pci/devices/** r, | ||
| + /sys/bus/pci/devices/ r, |
niemeyer
Aug 23, 2017
Contributor
Has this change been tested? Why was the prior case necessary and why is it not needed anymore now?
This also seems unrelated to device tagging.
adglkh
Aug 24, 2017
Contributor
We changed this rule because /sys/bus/pci/devices/ should be filled with symlinks, not actual files, and apparmor resolves symlinks. Also see here
https://github.com/adglkh/snapd/blob/1f4a0fe9c464e805afc9ccfe241b96b14d13248b/interfaces/builtin/opengl.go#L48-L50
The prior case matches any file or directory in or under /sys/bus/pci/devices/. It seems to be not needed anymore now
The same for broadcom_asic_control interface.
https://github.com/snapcore/snapd/pull/3617/files/1f4a0fe9c464e805afc9ccfe241b96b14d13248b#diff-5ef61751d67fe46b2e4b8167e20330c8R48
Yes, it's unrelated to udev tagging rule. It makes more sense to fix it in a separated PR.
Sorry about that.
mvo5
Aug 29, 2017
•
Collaborator
I reverted this change now - please open a new PR with this particular change. We are keen to land this one this is why I did the change :)
niemeyer
approved these changes
Aug 25, 2017
LGTM assuming we drop the unrelated opengl change from this PR (okay for another, but let's please test the change in real-world use first). For the other point, LGTM given comments from @jdstrand.
Thanks for the PR, by the way!
mvo5
added some commits
Aug 29, 2017
|
I changed the opengl.go as suggested by Gustavo and de-conflicted. |
|
This is failing currently in |
mvo5
added some commits
Aug 29, 2017
| @@ -37,9 +37,5 @@ execute: | | ||
| actual=$(snap install --channel beta --devmode $DEVMODE_SNAP) | ||
| echo "$actual" | grep -Pzq "$expected" | ||
| - echo "Install network-manager and do basic smoke test" |
mvo5
Aug 29, 2017
Collaborator
I removed this as it is racy in this PR at least. #3825 is a better test
|
The changes since my last review approval look fine. +1 |
adglkh commentedJul 25, 2017
It's a long-standing bug in snapd.
https://bugs.launchpad.net/snapd/+bug/1675738
We have some interfaces using udev tagging, but quite a few interfaces are still without udev tagging. So when people create a snap which has a combination of udev tagging plugs and none udev tagging plugs, an issue occurs due to device access denied since snap-confine only loads udev rules and creates a device cgroup for the tagged devices, excluding untagged ones.