-
Notifications
You must be signed in to change notification settings - Fork 30
libvirt: apparmor denies reading from /var/lib/libvirt/images/ #2083
Comments
Total shot in the dark, but if you have selinux enabled it might be denying it. |
Host: Ubuntu 17.04 x64 grep CONFIG_FW_CFG_SYSFS /boot/config-$(uname -r)
|
Does |
removed apparmor and kvm started properly |
@lucab sure, the hostname only |
I also have this same issue. Ignition file exists and is valid. Here is version information from virsh. I'm on ubuntu 16.04 |
My issue ended loading the file ended up up being with /etc/libvirt/libvirtd.conf and needing to turn security off and then restarting libvirtd service. |
@funwun did you ever figure this out? |
Yeah you are correct it is. If I check the app armor status I can see libvirt in enforcing mode:
|
+1 apparmor
Fixed by adding
In |
+1 on adding
to |
So the problem is that our doc examples use We should either find an allowed readable path and fix our the doc, or ask upstream to consider an entry for our usecase. For reference, the current upstream apparmor example config doesn't seem to offer us many options: https://github.com/libvirt/libvirt/blob/4d7384eb9ddef2008cb0cc165eb808f74bc83d6b/examples/apparmor/libvirt-qemu |
The /var/lib/libvirt/images directory is the default path that libvirt defines for storage. Any distro that has a policy denying use of that directory is seriously broken and needs to be fixed. |
I agree that we have the default paths upstream and those should work everywhere. |
@cpaelzer then I am not sure anymore, but people in this thread seem to be reporting that the ubuntu apparmor policy is denying that path. But I'm not familiar with apparmor nor libvirt, so I may be missing some details. For clarity, we don't ship libvirt in ContainerLinux, and this ticket is about running our images via libvirt on other distros (two of them being ubuntu 16.04 and 17.04). |
Odd, let me outline how it is supposed to work. Seeing that the workaround was to add to /etc/apparmor.d/abstractions/libvirt-qemu implies that not libvirt but the guest (=qemu) wasn't able to access the file. virt-aa-helper is allowed to read these paths:
Now when a guest is spawned and apparmor is set as the security modules two things happen:
In case a user is reporting an apparmor deny against that I'd assume for their case virt-aa-helper was unable to add the rule.
To shortcut that for the case here this is a user/config error and not a libvirt bug, let me outline why.
That is a manual qemu commandline addition outside of the scope what libvirt manages. Unfortunately there are no per-guest overrides (yet - I'm working on it as soon as confidtional if works in apparmor). So for now one has to edit /etc/apparmor.d/abstractions/libvirt-qemu to match what one added to the guest cmdline. But for that I'd strictly vote against: Or if you like maybe That would mean a malicious attacker breaking out of a guest can at least only read those files instead of all other guests images. To allow to fix that in libvirt we would need one of two things
|
Thanks for highlighting the -fw_cfg parameter usage here. I should point out that although this is exposed to the end user via -fw_cfg, and looks like a convenient way to get information into the guest OS, this is generally discouraged by QEMU developers. The principal purpose of the "fw_cfg" mechanism is communication between QEMU and the firmware. There are a fairly limited number of slots available for passing information, and so long term there's no guarantee that there will be spare slots available for end user application usage in this way. Thus we're not likely to expose '-fw_cfg' in libvirt XML explicitly. Recognising the usefulness of this conceptual approach though, I recently made it possible to use the SMBIOS "OEM strings" facility in QEMU and libvirt (https://libvirt.org/formatdomain.html#elementsSysinfo) to pass data into the guest. This will be available in QEMU 2.12, and libvirt 4.1.0. We're encouraging applications to include an application specific name prefix in the OEM strings entry so they can co-exist eg
So I'd encourage support of "OEM strings" as an alternative option to "fw_cfg", with eventual discontinuation of fw_cfg, once support for OEM strings is widely available in distros (will take a few years to penetrate) |
Thanks Daniel - good to know, |
@cpaelzer nothing todo from security pov since the data is passed inline, no references to external files on disk, so there is nothing to grant access to. |
Thanks both for the detailed insights! @berrange we'll look into OEM strings for the future. "fw_cfg" is being used by ignition for passing provisioning configuration since some time. @cpaelzer then I guess we'll suggest adding a wildcard rule for ignition files to our doc. If per-guest overrides are under work, it would be nice in the future to have some standardized path for user provided guest-read-only stuff (either generically or specific for fw_cfg). |
I was unsure on your suggestion, so I polled for opinions on the libvirt mailing list |
@berrange I built qemu 2.12-rc3 and added a file to a vm with Ignition configs definitely end up being bigger than 1 KB, so that's not really a workable replacement if we can't up that limit. Also is there a chance of being able to reference a file (something like |
@dgonyeo thanks for testing that, you've uncovered a horrible bug in QEMU. While SMBIOS has no limit on string length, QEMU's command line option parser is arbitrarily truncating options at 1024 bytes, with no warning, silently discarding any further data. I'm going to fix that to actually report an error message instead of continuing to run with garbage data. So yeah, unfortunately this means you can't use SMBIOS right now :-( Your suggestion to allow reference to an external file is a useful one, so I'll look at that too. |
For the record, patch series removing length limits in QEMU command-line parsing. The changes did not make QEMU 2.12. |
I think libvirt should do what I did in https://github.com/cgwalters/playground/commit/f2b67e50bc7f44d4b2e76ac6f3e5bbfe070819da#diff-f1a5248af69a24af73c52a6b2e565df6R75 and pass the config as a file descriptor. Since libvirt uses C it could even use memfd or |
The length limits were removed in QEMU 3.0. |
Support for OEM strings filed as coreos/ignition#656. |
NVMe drives are attached via extra qemu commands, this causes launching of guests to fail as qemu cannot access the drives. On Fedora, setting the right ownership of the drives seems to make this work with SELinux. However this is not enough on Debian and Ubuntu where Apparmor still blocks reading of /var/lib/libvirt/images. As this is designed for dev work, this change disables the security driver for qemu to avoid this problem. It's better than disabling SELinux. This change adds a new variable `virt_infra_security_driver` which lets you set the driver you want to use. It is set to "none" by default in order to disable it. Depending on your host, set this in your kvmhost vars to either "selinux" or "apparmor" if you want to keep it enabled for your system. If someone knows of a proper fix for Debian/Ubuntu (Apparmor?) then please let me know. For a good explanation, see here: coreos/bugs#2083 (comment)
NVMe drives are attached via extra qemu commands, which causes launching of guests to fail as qemu cannot access the drives. On Fedora, setting the right ownership of the drives seems to make this work with SELinux. However, this is not enough on Debian and Ubuntu where Apparmor still blocks reading of /var/lib/libvirt/images. As this is designed for dev work, this change disables the security driver for qemu to avoid this problem. It's better than disabling SELinux and Apparmor entirely. This change adds a new variable `virt_infra_security_driver` which lets you set the driver you want to use. It is set to "none" by default in order to disable it. If you want to keep it enabled, then set this in your kvmhost vars to either "selinux" or "apparmor" depending on your host. The proper fix is probably to add specific rules for specific guests, but I'm not sure that's possible with Apparmor. Another option is to add an Apparmor rule to allow read access on all nvme drives, which is better than the whole directory or disabling completely. For a good explanation, see here: coreos/bugs#2083 (comment)
NVMe drives are attached via extra qemu commands, which causes launching of guests to fail as qemu cannot access the drives. On Fedora, setting the right ownership of the drives seems to make this work with SELinux. However, this is not enough on Debian and Ubuntu where Apparmor still blocks reading with an error like this: [53928.386242] audit: type=1400 audit(1588465721.729:1232): apparmor="DENIED" operation="open" profile="libvirt-c814c482-e1f0-4c47-ba9f-2b354f89d0e9" name="/var/lib/libvirt/images/example-ubuntu-eoan-data-nvme.qcow2" pid=1700 comm="qemu-system-x86" requested_mask="r" denied_mask="r" fsuid=64055 ouid=64055 As this is designed for dev work, this change disables the security driver for qemu to avoid this problem. It's better than disabling SELinux and Apparmor entirely. This change adds a new variable `virt_infra_security_driver` which lets you set the driver you want to use. It is set to "none" by default in order to disable it. If you want to keep it enabled, then set this in your kvmhost vars to either "selinux" or "apparmor" depending on your host. The proper fix is probably to add specific rules for specific guests, but I'm not sure that's possible with Apparmor. Another option is to add an Apparmor rule to allow read access on all nvme drives, which is better than the whole directory or disabling completely. Add the following to /etc/apparmor.d/usr.lib.libvirt.virt-aa-helper /var/lib/libvirt/images/*nvme.qcow2 r, And restart apparmor service. For a good explanation, see here: coreos/bugs#2083 (comment)
Issue Report
Bug
Container Linux Version
CoreOS: 1409.7.0
libvirt xml file
QEMU emulator version 2.8.1.1
-rwxrwxrwx 1 libvirt-qemu kvm 262 Jul 31 12:49 config.ign
I get this error when I start vm
error: internal error: process exited while connecting to monitor: 2017-07-31T04:52:22.223191Z qemu-system-x86_64: -fw_cfg name=opt/com.coreos/config,file=/var/lib/libvirt/images/config.ign: can't load /var/lib/libvirt/images/config.ign
And I use this script: https://gist.github.com/euank/7c030ce123fc35d71361c25b69abe3d0, same result
The text was updated successfully, but these errors were encountered: