Nicer AppArmor profiles

Posted on Apr 15, 2020

Usually your AppArmor profile would look something like this:

#include <tunables/global>

/usr/lib/colord {
  ...
}

Now if we check if our profile is actually used:

$ ps axZ | grep '^/usr/lib/colord'
/usr/lib/colord (enforce)  4466  ?  Ssl  0:00 /usr/lib/colord

The Z parameter makes ps print the AppArmor profile name, or in the case of selinux the context of the program. /usr/lib/colord (enforce) tells us what AppArmor profile is used and in which mode it is. Another option you can see there is complain. With long binary paths this can become ugly very quickly.

As you might have guessed. I learned something new today and there is a solution to this.

#include <tunables/global>

profile colord /usr/lib/colord {
  ...
}

Now if we check the profile for colord, we get the following:

$ ps axZ | grep '^colord'
colord (enforce)  30945 ?  Ssl  0:00 /usr/lib/colord

This is supported in AppArmor since 12 years. So it should be safe to use in packages as well.

But why?

Well of course the most obvious reason is … seeing the status is much nicer. Be it via ps axZ or aa-status. Though is not the only advantage. If you want to address other profiles it is pretty annoying to do that in a distribution agnostic way, because the profile gets addressed with the path. With named profiles, we still have to have an ugly path in the profile for the program. But other profiles can address the profile via a nice name. Last but not leat AppArmor 3 will start emitting warnings about those ugly old profile names.

Changes required

Of course just changing the profile name in the beginning is not everything. Let’s take this simple profile:

#include <tunables/global>

/usr/bin/master {
  /usr/bin/something Px -> /usr/bin/master//something
  profile something {
  }

  signal (send) peer=/usr/bin/master//*,

  change_profile /usr/bin/master//*,
}

If we port it to the new syntax it will look like this.

#include <tunables/global>

profile master /usr/bin/master {
  /usr/bin/something Px -> master//something
  profile something {
  }
  
  # same for ptrace/dbus
  signal (send) peer=master//*,

  # sadly this does not work on 2.12.3 yet
  # but on newer AppArmor versions it should work.
  change_profile master//*,
}

Happy porting of your profiles to the nicer syntax!