[apparmor] restrictions on profile names

John Johansen john.johansen at canonical.com
Sun Apr 2 03:51:51 UTC 2017


There has been work upstream to bring generic LSM stacking to the
Linux kernel. If this happens it will require changes to apparmor,
specifically around the proc/<pid>/attr interfaces that apparmor
shares with other lsms. Currently only a single LSM can use these
interfaces, however with full lsm stacking there will need to be some
form of sharing. The current design has these interfaces being
multiplexed by using lsm name tagging

eg.

 > cat /proc/self/attr/current
 lsm1='v1'lsm2='v2'lsm3='v3'

while multiplexing these interfaces is not the only possibility, any
option will require changes to apparmor, and I would like to propose
we begin making changes that will ensure apparmor is ready no matter
what solution is chosen. AppArmor's problem with these interfaces
comes down to it allows arbitrary characters to be read and written,
making it impossible for the generic infrastructure to parse out what
is/should be apparmor's. The problem can be split into two distinct
parts, what apparmor returns when the interface is read and what
apparmor allows/requires be written to the interface.

The read problem is basically what characters are allowed in the
profiles name. Currently apparmor allows any character except \000 as
part of a profile name that begins with / (any valid file path), other
profile names are more restricted but the exact restrictions are
inconsistent and have never been formalized. Arbitrary characters for
a profile name are problematic as 3rd partly applications and generic
infrastructure must be able to cope and display the label (eg. ps,
pstree, ...). These applications do not handle the apparmor label well
when there are control characters etc, embedded. Nor does it make it
easy for a generic infrastructure to be able to tease apart the
apparmor label from other lsm labels.

So I propose we standardize on a set of printable characters for
profile names. This will mean that profiles should be defined with a
name separate from their attachment, ie.

  profile foo /usr/bin/bar { ... }

but even in cases where this is not the case we can have the parser
convert the name to a valid set using a well defined
transform. Somewhat like the standard we already employ for profile
files in /etc/apparmor.d/.  However even with such support we should
encourage the movement to none attachment based profile names, as they
are easier to write policy around and shorter (which is beneficial
when stacking is used).


The write issue is harder, in that \000 is allowed, even required, and
we use the size of the write to determine how much input their really
is. This is required to continue to allow interfaces like change_hatv
to continue to work, so instead of restricting the write input I
propose we move the writes to a custom apparmor interface. For most
applications the details can be hidden behind libapparmor. Basically
we would provide

  apparmor/current
  apparmor/exec
  apparmor/prev

files in apparmorfs. Since writes are already restricted to be done
only by the current task, we don't loose anything by not writing to
the tasks attr. Once this interface is up, and the library is using
it, we can deprecate writing to the proc interface in apparmor,
defaulting to reject writes, but providing a sysctl to allow them. In
this way we can find and migrate direct users of the current interface
to the new one without breaking them.



More information about the AppArmor mailing list