host Apparmor rules are applied to guests in spite of guests loading new rules

Bug #876968 reported by Clint Byrum
16
This bug affects 3 people
Affects Status Importance Assigned to Milestone
lxc (Ubuntu)
Fix Released
Medium
John Johansen

Bug Description

I had an old stale apparmor profile from mysql that did not allow writing to /run/mysql/mysqld.sock on my 11.10 host system. Upon trying to install and run mysqld in an oneiric container, it was unable to start because apparmor was denying it access:

[48692.230635] type=1400 audit(1318893995.329:62): apparmor="DENIED" operation="mknod" parent=9502 profile="/usr/sbin/mysqld" name="/run/mysqld/mysqld.sock" pid=14293 comm="mysqld" requested_mask="c" denied_mask="c" fsuid=103 ouid=103

The rules inside the guest for apparmor were permissive of this, but the host rules were not.

It seems to me that apparmor should be encapsulated at the same level as LXC containers, otherwise guests will not be able to define their own rules for their own filesystems.

TEST CASE:

create an apparmor rule in /etc/apparmor.d/usr.bin.faketouch

Contents:
#include <tunables/global>

/usr/bin/faketouch {
    #include <abstractions/base>
    /lib/* r,
    /var/run/* w,
}

sudo cp /usr/bin/touch /usr/bin/faketouch

Run /lib/init/apparmor-profile-load usr.bin.faketouch

Create an oneiric container

lxc-create -t ubuntu -n test-apparmor -- -r oneiric

Login to the container and try to touch /run/foo

sudo /usr/bin/faketouch /run/foo

should be denied..

Then create /etc/apparmor.d/usr.bin.faketouch

#include <tunables/global>

/usr/bin/faketouch {
    #include <abstractions/base>
    /lib/* r,
    /run/* w,
}

inside the container run

sudo /lib/init/apparmor-profile-load usr.bin.faketouch

This should enable it, but

sudo /usr/bin/faketouch /run/foo

Will fail and on the host kernel a DENIED message will be shown.

ProblemType: Bug
DistroRelease: Ubuntu 11.10
Package: lxc 0.7.5-0ubuntu8
ProcVersionSignature: Ubuntu 3.0.0-12.20-generic 3.0.4
Uname: Linux 3.0.0-12-generic x86_64
NonfreeKernelModules: nvidia wl
ApportVersion: 1.23-0ubuntu3
Architecture: amd64
Date: Mon Oct 17 16:30:25 2011
InstallationMedia: Xubuntu 10.10 "Maverick Meerkat" - Release amd64 (20101008.1)
ProcEnviron:
 PATH=(custom, user)
 LANG=en_US.UTF-8
 SHELL=/bin/bash
SourcePackage: lxc
UpgradeStatus: Upgraded to oneiric on 2011-07-14 (95 days ago)
mtime.conffile..etc.default.lxc: 2011-10-12T10:35:05.438801

Revision history for this message
Clint Byrum (clint-fewbar) wrote :
Revision history for this message
Serge Hallyn (serge-hallyn) wrote :

Apparmor is MAC - in my opinion it's not valid to have a container guest
specify its own policy.

However, the container should be entering a domain which protects the
host from the container, and in which executing any programs do not
cause more domain transitions (unless specified by the container's
policy).

This is something I want to discuss at UDS and implement during the
precise cycle.

Changed in lxc (Ubuntu):
assignee: nobody → John Johansen (jjohansen)
importance: Undecided → Medium
Revision history for this message
Serge Hallyn (serge-hallyn) wrote :

Assigning to jjohansen just to toss him a warning that I'm looking to talk to him at UDS :)

Setting to medium priority because while 'a guest loading new rules' is invalid, host apparmor rules for daemons in the guest should not be applied.

Revision history for this message
John Johansen (jjohansen) wrote :

Well I won't agree the guest shouldn't have its own policy (it depends on your use case), but I do agree the host should be able to set a domain to protect it self from the guest, but until AppArmor supports policy stacking the solution is either or.

The solution depends on what confinement is sought.

1. If the guest is to have its own policy, then the host needs to create a new policy namespace, and then it needs to transition the guest to the new namespace. Guest policy will then be loaded into the new namespace, and will not generally* conflict with system policy.

Setting up apparmor namespaces is a little clunky at the moment (a better interface is coming).
  You create a new dummy profile, and load using apparmor_parser -n <namespace> <profile>

This creates the namespace if it doesn't exist, and loads the dummy profile (the host can inject profiles into the container namespace). You then enter the namespace using the aa_change_profile call from libapparmor, unfortunately the command line interface to this isn't available in current releases, but I can provide the simple perl program. I would recommend transitioning into the unconfined profile (created by default as part of namespace creation) instead of the dummy, this allows the guest to behave as it would for normal system boot.

Instead of documenting the everything in detail here I am working on updating the wiki, and will drop a link to it here.

* The policy doesn't conflict but there are places where the guest can see that it is in a namespace. Eg. Messages from the kernel audit framework.

2. If the host is to confine the guest and disallow it from loading policy. You need to create a profile for the guest, it can be very broad but it should not allow capability mac_admin.

Long term the solution will be to use, apparmor namespaces as in 1, but with the aa_stack_policy command. Which will allow the host to retain its own policy and allow the guest to have a separate policy set that is controlled by the host. The goal is to allow a fake stacking for P, where the host policy is the unconfined state. This will allow for the same functionality of 1 but provide a stable api moving forward for when policy stacking is fully supported.

Revision history for this message
Serge Hallyn (serge-hallyn) wrote : Re: [Bug 876968] Re: host Apparmor rules are applied to guests in spite of guests loading new rules

Quoting John Johansen (<email address hidden>):
> Well I won't agree the guest shouldn't have its own policy (it depends
> on your use case), but I do agree the host should be able to set a
> domain to protect it self from the guest, but until AppArmor supports
> policy stacking the solution is either or.
>
> The solution depends on what confinement is sought.
>
> 1. If the guest is to have its own policy, then the host needs to create
> a new policy namespace, and then it needs to transition the guest to the
> new namespace. Guest policy will then be loaded into the new namespace,
> and will not generally* conflict with system policy.

That's great - can the guest's namespace have constraints placed on
it by the host rules, which all domains in the guest namespace will
be subject to?

Revision history for this message
John Johansen (jjohansen) wrote :

>> 1. If the guest is to have its own policy, then the host needs to create
>> a new policy namespace, and then it needs to transition the guest to the
>> new namespace. Guest policy will then be loaded into the new namespace,
>> and will not generally* conflict with system policy.
>
> That's great - can the guest's namespace have constraints placed on
> it by the host rules, which all domains in the guest namespace will
> be subject to?

Not currently, the plan is to allow for a restrictive stack of profiles where the
parent (host) rules will constrain on guests in the namespace, but its not
available yet.

Changed in lxc (Ubuntu):
status: New → Confirmed
Revision history for this message
Serge Hallyn (serge-hallyn) wrote :

This is fixed in precise, as containers now start in their own domain which will not transition further (i.e. to libvirtd).

Changed in lxc (Ubuntu):
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.