Hi all,

I'm working on Gitlab #692 [1] and would appreciate a quick
discussion/review/sanity check of the direction I'm planning to take before
I invest many days in a solution that misses some major consideration.

I'll provide a summary of the issue here and then lay out the two approaches
I'm considering.

The AppArmor sVirt driver creates & loads a dynamic AppArmor profile by passing
a domain's XML description to a separate program `virt-aa-helper` (see [2] for
more details).

When a device is hotplugged to a domain, the `virt-aa-helper` is called with a
flag (`-F`) which appends a rule for that device's backing resource to the
profile. The profile is reloaded from the XML description whenever a device is
hotunplugged.

However, the XML description for some devices does not contain enough
information to create the corresponding AppArmor rule. When a profile containing
a dynamic rule is reloaded, the dynamic rule is lost, and the device fails (this
has been observed with macvtap devices).

A similar situation occurs when temporary write access to snapshot layers is
needed during block-commit; the `virt-aa-helper` is called with `-F` to add the
temporary access and the profile is reloaded at the end of the operation to
remove it again. However, this can have the unintended side-effect of wiping
out other temporary accesses (for concurrent blockcommits) or removing access
for devices added with `-F` (macvtap).

A solution must:
- Be persistent across libvirtd restarts
- Correctly synchronize concurrent profile modifications

We've conceived of two broad approaches to this issue:
1. Add fields to the domain XML schema (and persist them) so that the profile
   can be correctly generated using only the domain's XML description.
2. Create a separate XML file `/etc/apparmor.d/libvirt/libvirt-UUID-dynamic.xml`
   with only the information needed to produce the dynamic rules; access would
   be synchronized by a lock in libvirtd.
   `virt-aa-helper` would consume this file every time it runs; the file would
   be removed on Domain shutdown.

Option 1 (Add fields to Domain schema) Concerns:
================================================
- User-visible schema changes
- Do additional fields make sense in the domain schema? e.g.
  - a macvtap device path `/dev/tapX`
  - permissions info in `backingStore` elements
- It may be non-trivial to chase down every device that could be affected by
  this issue and plumb through the additional fields (i.e. a complete solution
  may not be possible)

Option 2 (Separate AppArmor XML) Concerns:
==========================================
- User-visible additional file
- Not generalizable for (future) sVirt drivers that depend on synchronizing a
  global resource
- May require adding remove/restore hooks for the following sVirt interfaces:
  - virSecurityDomainSetImageFDLabel domainSetSecurityImageFDLabel;
  - virSecurityDomainSetTapFDLabel domainSetSecurityTapFDLabel;

I'd appreciate any input you'd be able to provide regarding the above
trade-offs; specifically looking for guidance on what you would consider merging
(in contrast to previous approaches [3]).

Thanks very much for taking the time to review this,
~Wesley Hershberger
Canonical Support

[1] https://gitlab.com/libvirt/libvirt/-/issues/692
[2] https://gitlab.com/apparmor/apparmor/-/wikis/Libvirt
[3] https://www.mail-archive.com/[email protected]/msg07703.html

Reply via email to