[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