Skip to content

Editing an apparmor profile

I had Suckless' Surf installed but had troubles using it with pages not opening and apparmor denies in dmesg. This post is not a tutorial but just a reminder on how to edit the profile for an executable, in this case /usr/bin/surf.

The profile is located at /etc/apparmor.d/usr.bin.surf and can be augmented with the file at /etc/apparmor.d/local/usr.bin.surf. The second file is included in the first one, and I indented its content similarly as how it would be indented had it been written directly in the including file (but I’m not sure this is required).

The reference manpage is apparmor.d, but it is long and I found it difficult to rapidly extract information from it so here’s some info I used:

  • There are variables defined like @{PROC} and @{pid}, defined in files under /etc/apparmor.d/tunables. There’s an undocumented @{uid}, but it does match a general regexp and does not identify the current user (and this is probably why it is undocumented).
  • You can get apparmor logs the output of dmesg. Look for the logs with apparmor="DENIED". The class will indicate what kind of access you need to tweak.
  • File access notes: class="file" will require a file rule in the profile which is logged under the profile key, eg profile="/usr/bin/surf". The profile file’s name is obtained by replacing / in the file path by .. The operation indicates which right should be authorised, eg operation="open". For files, the denied_mask key shows which right was denied. Of note is that for files, there’s a operation="connect" possible, and it has to be fixed with a file access rule (r or w according to the denied_mask)
  • There are also operation="dbus_method_call logs. Look at the bus, member and interface keys to add rules like shown below.

With this info, the following content of the file /etc/apparmor.d/local/usr.bin.surf should be more approachable:

  # File system
  @{HOME}/** r,
  /usr/share/libdrm/amdgpu.ids r,
  @{PROC}/zoneinfo r,
  @{PROC}/@{pid}/cgroup r,
  @{PROC}/@{pid}/statm r,
  /sys/class/dmi/id/chassis_type r,
  /sys/devices/virtual/dmi/id/chassis_type r,
  /sys/firmware/acpi/pm_profile r,
  /sys/fs/cgroup/user.slice/** r,
  # Note @{uid} does not explicitly match current user, it is at this time just a regexp
  # defined in /etc/apparmor.d/tunables/kernelvars
  # This is a connect complain, but is still about write permission on the bus as a file:
  #  apparmor="DENIED" operation="connect" class="file" profile="/usr/bin/surf" name="/run/user/1000/bus" pid=17092 comm="WebKitWebProces" requested_mask="w" denied_mask="w"
  /run/user/@{uid}/bus rw,
  /run/user/@{uid}/at-spi/bus_0 rw,


  # from firefox
  #include <abstractions/dbus-accessibility-strict>
  dbus (send)
       bus=session
       peer=(name=org.a11y.Bus),
  dbus (receive)
       bus=session
       interface=org.a11y.atspi**,
  dbus (receive, send)
       bus=accessibility,

  # manual additions
  # operation="dbus_method_call"  bus="system" path="/net/hadess/PowerProfiles" interface="org.freedesktop.DBus.Properties" member="GetAll" mask="send"
  dbus (send)
       bus=system
       interface=org.freedesktop.DBus.Properties
       member=Get,
  dbus (send)
       bus=system
       interface=org.freedesktop.DBus.Properties
       member=GetAll,
  # operation="dbus_method_call"  bus="system" path="/org/freedesktop/RealtimeKit1" interface="org.freedesktop.RealtimeKit1" member="MakeThreadRealtimeWithPID" mask="send" name=":1.33" pid=16054 label="/usr/bin/surf" peer_pid=1908 peer_label="unconfined"
  dbus (send)
       bus=system
       interface=org.freedesktop.RealtimeKit1
       member=MakeThreadRealtimeWithPID,