[Apparmor-dev] AA3 - file rules

John Johansen jjohansen at suse.de
Thu Jan 1 02:49:23 MST 2009


Well I should have had this out weeks ago, sorry it has taken so long.


AppArmor 3 will see an extension of file permissions.  Below is a list
of several possible extensions.  Some of them will happen, while others
are abilities that have been requested but their inclusion is uncertain,
and are very open to modification.


1. Permission first file rules
  Curretly AppArmor file rules specify a pathname followed by the
  granted permissions, eg.

    /a/pathname  rw,

  It has been requested several times allowing permissions to appear
  before the path name. eg.
      rw  /path/name,
      rw  "/path/name/with/comma/at/its/end,",

  This requires that pathnames with commas at their end be quoted.

  Moving to a permissions first order allows for easier alignment
  of permissions which is better for visual inspection.

  This ability is already partially supported by the parser in
  AppArmor 2.3, but not by the tools.  The tools should support both
  formats using the one set as the default in a configuration option.
  The question remains open as to which order should be the default.


2. better utf8 support
  Currently AppArmor treats path names as a stream of bytes both in the
  kernel and in the user space tools.  This works well for most matching
  but can produce poor results when character sets are used.

  The user side tools will be extended to provide better support of
  utf8, by making them aware of the locale, and also providing a
  meta tag for profiles if so desired.  The policy compiler will
  then be able to correctly encode utf8 characters into alternation
  byte streams for the kernel.

  The kernel matching routines will continue to treat all pathnames
  as a stream of bytes.


3. Pathnames with using regular expressions
  AppArmor currently uses a globbing syntax that some users have found
  limiting.  It has been requested by several users that AppArmor add
  support for true regular expressions.  AppArmor's policy compiler
  is capable of this and internally turns globbing into regular
  expressions, so it is only a matter of deciding on syntax.


  The proposed syntax for regular expressions is a subset of extended
  regular expression (POSIX.2)
  - rules will begin with ^ and end with $ since all AppArmor rules
    are anchored.
  - . will match any character except '\0'
  - \ is used to escape special characters
  - [ ] is used for character sets
  - [^ ] is used for inverted character sets
  - ( ) is used for grouping
  - | alternation
  - * 0 or more matches
  - + 1 or more matches
  - ? 0 or 1 matches

  All matching is greedy to the left and there will be no back
  references.

  Eg.
    ^/some/(path|other).*$  rw,


4. Special kernel variables
  There are a few special cases where a kernel side variable would
  provide a much tighter match, enhancing a policies security (eg.
  /proc/) AppArmor 3 will see the addition of 3 special variables that
  will get expanded at runtime.
    @{pid} - process id
    @{tid} - task id
    @{uid} - the user id

  There is no plans to provide a kernel side username, or user directory
  match.  The username would require loading mapping of uids to
  usernames which would have to be kept in sync with the password
  database and would not handle having multiple usernames aliased to a
  single uid.  The user home dir would have similar problems.

  A special chroot variable @{chroot} may be considered depending on
  how extended chroot handling is done.


5. Extended owner rules
  AppArmor 3 will see an extension of owner conditional rules allowing
  specifying exact user ownership.  This ownership test does not
  override dac permission checks.  The information for the ownership
  test will come from the parser reading the user database and
  converting user names to uids, which then get loaded to the kernel.

    #allow reading of /some/file if it is owned by tom
    owner=tom /some/file  r,

    #file access with multiple owner constraints
    owner=(tom,dick,jane) /some/file rw,

    #specify an owner uid instead of an owner
    owner=(#101) /some/file rw,

    #mixed user, uid specification
    owner=(tom,#101)  /some/file  rw,

    #specifying the owners in a variable
    owner=(@{foo_users})  /some/file  rw,

    #deny access to a file owned by root
    deny owner=root /some/file rw,


  One of the open questions is if the negative case is needed and if
  so, what syntax should be used.

    owner!=(tom, dick)  /some/file  rw,  # allow access to /some/file if
                                         # not owned by tom or dick

    !owner /some/file rw,                # allow access to /some/file if
                                         # not owned by the current
					 # fsuid

  Another point to consider is that updates to the user data base will
  require at least a partial reload of AppArmor profiles.  This breaks
  down into a couple cases, that are the same for both positive and
  negative ownership rules.

    - Adding new user does not require profile reload unless the user is
      added to policy
    - Modifying an existing user uid requires reloading policy if a
      profile refrences the users name

  One of the open questions is if a full profile reload is necessary or
  whether a special table for user information should be loaded.  So
  that updates to the user database rely only on loading the current
  user database.

  Another point to note is that reloading profiles/user db information
  will not be automatic.  Updates to user db will require the admin to
  run the reload script, or have the tool used to modify the db do it.

  The addition of owner conditional rules means that finer grained
  mediation of chown is required for processes with capability chown.
  The details of how this should be done is touched on in section 6.

5.1 change of owner syntax?
  The current owner rule syntax is not as explicit as it could by that
  the rule is conditional on ownership.  I am unsure if the current
  syntax is sufficient or whether tweaking the syntax would be helpful
  for the average user.

   eg.
     owner /foo/bar rw,

   could be rewritten as
     if owner /foo/bar rw,

   It is a small change but does emphasize that the rule is conditional
   on file ownership.


6. Attrs and xattr permissions

  The writing of file ownership (chown) and the security xattrs of
  a file beyond the current file write mechanism.  The exact level of
  detail is yet to be determined.

  All of these abilities will require the accompanying capability be
  specified in the profile.

  6.1 chown
  File chown could be limited by either a per profile mask of uid or
  it could be done per file.

    chown (tom, jane),			# profile level mask

   vs. file level
     /some/file chown=(tom, jane),
   or
     chown=(tom, jane) /some/file,
   or
     chown /some/file (tom, jane),

  If done at a per file level, it will allowed to be conditional on file
  ownership and allow for chowning to any user.

    owner /some/file chown=(tom, jane),

    owner /some/file chown=(*),   #allow chown to any user if file owner


  6.2 security xattr
  The security xattr is similar to chown except instead of allowing a
  list of uids, it allows an undefined set of security attributes (which
  are currently unused).  It could be specified at a per profile level
  or at a per file level.

  Apparmor 3 will have is planned to have the most basic of code
  reserving the apparmor security namespace, for future use.  Though
  that plan could change dependant on other discussions.


7. Mount and mknod rules
  AppArmor's current mediation is mount and mknod is insufficient for
  all too many cases, in fact it fails even in wrapping trusted
  applications, which will be desirable for better ipc control.
  AppArmor 3 will pickup the ability to provide finer grained mediation
  to mount and mknod.

  7.1 Mount rules
  Mount rules will be able to control most aspects of a mount.  Taking
  on a form similar to the mount command.  The syntax could take on a
  fixed form like

    mount permissions type device -> /path,

  or more closely adhere to the mount command form of

    mount permissions [-t type] [-o options] device -> /path,

  The mount permissions will cover bind mounting, suid, etc.  And
  pattern matching will be allowed in each part of the rule (type,
  option, device, /path).

  It is currently undecided on how best to make mount rules conditional.
  On the euid, the fsuid and /path, device owner?

  7.2 Mknod rules
  Mknod rules will be handled similarily

  mknod type [major minor] -> /path,


8. Most Specific Match to resolve conflicts in x qualifiers
  Currently AppArmor accumulate permissions for rules and fails profile
  loading if there are overlapping rules with conflicting x qualifiers.
  AppArmor currently allows for a specific match to override the x
  qualifier of a pattern match. eg.
     ix /**,
     px /foo,
  will not cause a conflict while
     ix /**,
     px /foo*,
  and
     px /foo,
     ix /foo,
  conflict.

  It is desirable to generalize the specific match rule that is
  currently used to avoid conflicts.  This can be done by testing if one
  rule is a proper subset of the other.  Rules that partially intersect
  and have conflicting x qualifiers will still result in an error.

  eg.  none conflicting rules
    ix /foo/**,
    ix /*/b,
    px /foo/bar**,

  eg. conflicting rules
    ix /foo*,
    px /*bar,


9. Symlink permission
  Currently AppArmor allows traversals of symlink without any permission
  check.  The ability to mediate symlink traversals is desired but the
  question is at what level.

  Symlink traversal could be mapped to the read permission so that
  accessing the symlink file for traversal requires the same permission
  as reading the file.

  Another option is to have symlink traversal be its own permission,
  this could be specified with a new flag (t?) or with a new rule.
  symlink /foo/bar r, or traverse /foo/bar,

  A third option is to make the traversal permission a subset of the
  read permission so it is implicitly granted with the read permission
  but can be specified on its own when so desired.

  The first two proposals don't cover control of where the symlink
  traverses too. eg.
    traverse /foo/bar -> /some/file,

  I don't believe that this will be particularily useful as it can be
  approximated by granting symlink read permission on /foo/bar and
  access permissions for /some/file.

  The other thing to consider is whether the symlink mediation should be
  on all the time or it should be configurable by a global or per
  profile option.

  My current inclination is to go with what I think is the least complex
  solution which is mapping it to the r permission and having it always
  enabled.



More information about the Apparmor-dev mailing list