New test eliminating libvirt from the equation: # Create one backing chain and one normal image $ qemu-img create -f qcow2 /var/lib/libvirt/images/testdisk-nosnap.qcow2 100M $ qemu-img create -f qcow2 /var/lib/libvirt/images/testdisk-snap-base.qcow2 100M $ qemu-img create -f qcow2 -b /var/lib/libvirt/images/testdisk-snap-base.qcow2 /var/lib/libvirt/images/testdisk-snap-snapshot.qcow2 # Use a profile similar to those created by libvirt - our guest doesn't do much, so he doesn't need much $ cat > /etc/apparmor.d/qemu-testprofile << EOF # Test profile for bug LP: #1912214 #include profile qemu-testprofile flags=(attach_disconnected) { #include #include } EOF $ touch /etc/apparmor.d/local/extrarules $ apparmor_parser -r /etc/apparmor.d/qemu-testprofile # Start qemu into the monitor under control of an apparmor profile $ aa-exec -p qemu-testprofile -- qemu-system-x86_64 -serial none -monitor stdio -m 64 -display none # Attach and detach the disk (qemu) drive_add 0 if=none,file=/var/lib/libvirt/images/testdisk-nosnap.qcow2,format=qcow2,id=disk1 # This can be detached (e.g. to iterate the test) via (qemu) drive_del disk1 As-is this fails (expected) since it gets the access to the file blocked: [58147.954482] audit: type=1400 audit(1611040852.319:86): apparmor="DENIED" operation="open" profile="qemu-testprofile" name="/var/lib/libvirt/images/testdisk-nosnap.qcow2" pid=23222 comm="qemu-system-x86" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 Now we can "manually play to be libvirt" and append the rule and reload the profile. In another console we can do: $ echo '"/var/lib/libvirt/images/testdisk-nosnap.qcow2" rwk,' > /etc/apparmor.d/local/extrarules $ apparmor_parser -r /etc/apparmor.d/qemu-testprofile Once that is done the `drive_add` command above will work. Now if we allow the snapshot file but not the base image in apparmor. And then attach the snapshot, we expect qemu to parse the snapshot, identify the backing file and fail to access that. $ echo '"/var/lib/libvirt/images/testdisk-snap-snapshot.qcow2" rwk,' > /etc/apparmor.d/local/extrarules $ apparmor_parser -r /etc/apparmor.d/qemu-testprofile (qemu) drive_add 0 if=none,file=/var/lib/libvirt/images/testdisk-snap-snapshot.qcow2,format=qcow2,id=disk1 Could not open backing file: Could not open '/var/lib/libvirt/images/testdisk-snap-base.qcow2': Permission denied [58777.551226] audit: type=1400 audit(1611041481.906:96): apparmor="DENIED" operation="open" profile="qemu-testprofile" name="/var/lib/libvirt/images/testdisk-snap-base.qcow2" pid=23222 comm="qemu-system-x86" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 Perfect - still as expected. Now if we add both rules we expect this to work. $ echo '"/var/lib/libvirt/images/testdisk-snap-snapshot.qcow2" rwk,' > /etc/apparmor.d/local/extrarules $ echo '"/var/lib/libvirt/images/testdisk-snap-base.qcow2" rwk,' >> /etc/apparmor.d/local/extrarules $ apparmor_parser -r /etc/apparmor.d/qemu-testprofile (qemu) drive_add 0 if=none,file=/var/lib/libvirt/images/testdisk-snap-snapshot.qcow2,format=qcow2,id=disk1 And indeed it does work fine. This also works fine in the containers ... good, but no help for debugging this.