Archive:AppArmor 2 3 changes

Jump to: navigation, search

Version: 11.0 This article covers the new features of AppArmor 2.3, available in openSUSE 11.0.


Minor Semantic Changes

Append

File creation semantics have been changed slightly so that the append permission provides sufficient privilege to create a new file.

change_profile

The change_profile interface has been extended so that it can be used by an unconfined process to enter confinement. An unconfined process using change_profile can enter any loaded profile. For unconfined processes the change_profile interface differs from the set_profile interface in that it only applies to the current task while the set_profile interface can be used to change confinement on any task.



New tool: aa-repo.pl

aa-repo.pl allows direct access to the profile repository and the configuration used by logprof/genprof.



Extensions to Profile Specification

Profiles without attachment specification

AppArmor 2.3 allows for profiles that names do not reside in the filesystem namespace and thus can not be automatically attached to, ie. they will never match a program name.

Creating profiles without attachment is much the same as creating standard profiles except that the "profile" key word appears before the name of the profile.

Example

 profile An.unattached.profile {
   /foo/bar rw,
 }

The profile names have a few limitations, they can not begin with the ':' or '.' characters (though they may be used internally) and they can only contain whitespace characters if the name is quoted. Starting the profile name with '/' is the same as specifying a standard profile that will attach to a program of the same name.

Example

 profile /bin/ping {
     ...
 }

is the same as just doing

 /bin/ping {
     ...
 }

Uses for profiles that don't attach

Profiles don't provide confinement unless they are attached to a running program. Profiles without attachment specification will not attach to a program when it is invoked (the executable name will never match the profile name), nor can they be transitioned to through a standard px transition rule. For one of these profiles to be attached so it provides confinement either change_profile profile or the new named (specified) profile transition is used.

This type of profile provides for more flexibility and advanced uses such as providing roles, or specialized profiles for system utilities that generally should not be confined by a system wide profile. For example, grep generally should not have its own profile but, it can be useful to have a specialized profile for an invocation of grep from within a confined shell script.

Children (local) Profiles

Local profiles are an extension of AppArmor "hats". They are a profile that is embedded inside of a parent profile, that is used to provide tighter or alternate confinement for a subtask of an application.

A good use for local profiles is providing specialized confinement for utility programs launched by a confined application. In previous versions of AppArmor, if a global profile for the utility didn't exist or wasn't appropriate then the ix execute mode was the only choice for providing confinement to the utility application.

This means that utility application has the full privileges of the parent task which is not always desirable. Local profiles provide an alternative where the utility applications profile can be customized for the application that launches it.

Local profiles are specified just like standard profiles except they are embedded in a profile and the begin with the "profile" keyword.

Example

 /parent/profile {
..
profile local/profile {
..
} }

Local profiles can specify an attachment, but it will only ever get used with the new cx, or named profile transition rules.

Example

 /parent/profile {
..
profile /bin/grep {
..
} }

Hat and Local profile names

AppArmor "hats" are a local profile with some additional restrictions and an implicit rule allowing for change_hat to be used to transition to them. AppArmor "hats" may not contain their own "hats" but local profiles can contain their own local profiles and "hats". Local profiles that are not "hats" and can not be used with change_hat without an explicit hat rule.

"Hats" and local profiles are actually just standard profiles with special names. When a hat or Local profile is loaded, its name in the logs and as reported by ps -Z is the name of the parent profile and the name of the local profile separated by '//'.

Example

 /parent/profile {
..
^foo {
..
}
profile local.profile {
..
}
profile /bin/grep {
..
} }

Will show up as 4 profiles in the loaded profile listing.

 /parent/profile
 /parent/profile//foo
 /parent/profile//local.profile
 /parent/profile///bin/grep
 

External Local Profiles and Hats

With the knowledge that "hats" and local profiles are just standard profiles with using a standard naming convention it is possible to specify local profiles and "hats" external to a profile.

Example

 /parent/profile {
..
^foo, # rule allowing change_hat }
/parent/profile//foo {
..
}
/parent/profile//local.profile {
..
}
/parent/profile///bin/grep {
..
}

Notice that for the external profile to function, as a "hat", a hat rule must be specified in the profile.

Change_hat and Change_profile rules

AppArmor 2.3 provides change_profile rules that control domain transitioning via the change_profile API. Change_profile is similar to change_hat except it only provides a one way transition, and it can transition to any loaded profile.

The change_profile API can be used from confined and unconfined processes. For change_profile to succeed when done in a confined process, the confining profile must have a rule allowing the transition to the specified profile

Example

 change_profile -> a_profile,
change_profile -> /foo/bar,

Differences between change_hat and change_profile

Both change_hat and change_profile provide for an application directed profile transition, without having to launch a separate application.

Change_profile provides a generic one way transition between any of the loaded profiles. Change_hat provides for a returnable parent child transition where an application can switch from the parent profile to the hat profile and if it provides the correct secret key return to the parent profile at a later time.

Safety of Domain transitions and when to use them

The change_hat and change_profile domain transitions are less secure than a domain transition done through an exec. This is because they do not affect a processes memory mappings, nor do they close resources that have already been opened.

Change_hat is a specialized version of change_profile that has additional security implications, so we will look at change_profile first.

Change_profile provides a one way transition, that allows an application to go through a setup phase and then when setup is done, transition to a profile with less privileged. Any resources mapped or opened during the startup phase may still be accessible after the profile change but the new profile will restrict the opening of new resources, and will even limit some of the resources opened before the switch.

Specifically memory resources will still be available while capability and file resources (as long as they are not memory mapped) can be limited.

Change_profile is best used in situations where an application goes through a trusted setup phase and then can lower its private level.

Change_hat is designed to be used in situations where privilege is temporarily dropped and then required after a time. As such change_hat is restricted to where it can be safely used. Since change_hat stores the return secret key in the applications memory the phase of reduced privilege should not have direct access to memory. Also it is important that file access is properly separated, the hat can restrict accesses to a file handle but it does not close it. If an application does buffering and provides access to the open files with buffering, the accesses to these files may not be seen by the kernel and hence not restricted by the new profile.

Change_hat is best used in situations where an applications runs a VM or interpreter that does not provide direct access to the applications resources. An example of where it could add security value is apache's mod_perl and mod_php.

Profile namespaces

AppArmor 2.3 has the beginnings of support for the concept of profile namespaces. Profile namespaces provide a means for several sets of profiles to be loaded at the same time, with one set of tasks using the profiles in one set, while other tasks are using the profiles in a different set.

Profile namespaces will be useful for allowing different policy sets for different filesystem namespaces or vservers. However at this time only the most basic support of them is included, and the tools cannot handle them at all.

All profiles as currently specified belong to the default profile namespace, whose name is not displayed in log messages or when introspecting loaded profiles or confinement. So for all intents and purposes profile namespaces are hidden in the current release except when examining the source code.


New execute permissions

AppArmor 2.3 has some new options for execute permissions. In addition to the ix, ux, and px permissions present in AppArmor 2.1, there is a new cx permission, as well as the ability to specify a profile to transition to. Additionally each of these can be offered in an inherit fall back mode.

New transition mode cx

The new cx permission is like px except it specifies a transition to a child (also known as local) profile. Just as with px, cx specifies transitioning to a profile who's name matches the executable, except instead of searching the global profile set, only the local profiles of the current profile are search.

The cx profile transition combines with local profiles providing a way for an application to have alternate profiles for helper applications. For example a text based mail viewer could have a profile for /bin/grep, which the system doesn't confine by default.

The cx transition provides an alternative to using ix for utilities, providing the possibility of achieving tighter confinement.

Example

 /usr/bin/mutt {
..
/bin/grep cx,
profile /bin/grep {
..
} }

As with the ux and px profile transition modes, cx comes in both safe and unsafe variants. Cx is "safe" and has glibc sanitize the environment variables, while cx does not sanitize the environment variables.

currently cx transitions are limited to top level profiles and can not be used in hats and children profiles. This restriction will be removed in the future.

Named (specified) profile transitions

In addition to the cx transition mode AppArmor 2.3 adds the ability to specify exactly which profile will be transitioned to. This can be useful if multiple binaries should share a single profile, or if they should use a different profile than there name would specify.

Named profile transitions use -> to indicate the name of the profile that should be transitioned to.

Example

 /usr/bin/mutt {
..
/bin/** px -> shared_profile, }

The px in the rule indicates the transition will look for the profile in the global scope. If a cx is used the transition searches for a local profile.

Example

 /usr/bin/mutt {
..
/bin/** px -> shared_profile, /usr/*bash cx -> /bin/bash,
profile /bin/bash {
..
} }

Using cx in a named profile transition is a convenience and is equivalent to specifying px with the parent profile name properly prepended. ie. the cx line from the above example is equivalent to

 /usr/*bash px -> /usr/bin/mutt///bin/bash,

There is an implementation specific limit on how many named profile transitions can be specified in a profile. The limit in AppArmor 2.3 is 12.

Globbing with px/cx and named profile transitions

The px/cx execute permissions use the executable name to specify which profile to transition to, so when they are used with globbing they can specify many different profile transitions.

 ie. /bin/** px, Will transition to /bin/ping, /bin/cat, ... depending on the program being run.

Named profile transitions when combined with globing provide a many to one transition. ie. All programs that match the rule regardless of their name will transition to the specified profile.

When globbing is not used, a px transition is equivalent to a named profile transition to the file rule pathname.

 ie.
   /bin/ping px,
 is equivalent to
   /bin/ping px -> /bin/ping,


Profile transitions and inheritance fall back

The px, cx, and named profile transitions specify a hard dependency, in that if the specified profile does not exist, the exec will be failed.

AppArmor 2.3 introduces the ability to have an inheritance fall back so that instead of the program execution failing, it will succeed but inherit the current profile. This allows for a soft profile dependency, which allows for gradual or partial profile deployment.

To specify inheritance fall back ix is combined with px, cx into the pix and cix modes. The pix and cix modes can be used with named profile transition to provide inheritance fallback as well. The pix and cix modes like px, and cx have safe and unsafe versions.

Named Profile Transitions and Log Messages

Named profile transitions show up in the log as having the mode Nx and the name of the profile to be changed to is in the name2 field.



Link pair rules

AppArmor 2.3 introduces the ability to specify links as a source and destination pair providing even greater control over how hard links are created.

 link /link/file -> /target/file,

Link pair rules by default do not enforce the link subset permission test that the standard rules link permission requires. To force the rule to require the permission subset test the "subset" keyword is used.

 link subset /link/file -> /target/file,

The link permission expressed in the standard rule is equivalent to the following link pair rule

 link subset /path -> /**,

So the rule

 /path/name rwl,

is equivalent to

 link subset /path/name -> /**,
 /path/name  rw,
currently link pair rules are not supported by the tools but they will not be stripped so it is safe to update profiles containing them.



File rules conditional on file ownership

AppArmor 2.3 extends file rules so that they can be conditional upon the the user being the owner of the file.

To make a file rule conditional on the file being owned by the user the owner keyword is prepend to the rule.

Example

 owner /home/*/** rw,

Owner conditional rules accumulate just as regular file rules and are considered a subset of regular file rules so that if a regular file rule overlaps with an owner conditional file rule, the resultant permissions will be that of the regular file rule, since it specifies permissions regardless of ownership.

Example given the following rules

 owner /home/*/** rw,
 /home/*/foo rw,
The files matched by /home/*/foo do not have be owned by the user.

It is important to remember with owner rules that, like standard rules they are just a further restriction of DAC permissions, they do not grant additional permissions and the file must be accessible via the DAC permission test before it will be checked against the profiles permissions.

When using file ownership conditions with link rules the ownership test is against the target file. This enables forcing openwall style link restrictions, where to link to a file the user must own the file.

Example

 owner /** l,	# restrict hardlinks to user owned files
The ownership test of a file is done by testing the user of the confined process matches the owner of the file, specifically the processes fsuid (see man 2 setuid) is compared to the files uid.


Per rule audit control

AppArmor 2.3 provides the ability to audit given rules so that when they are matched an audit message will appear in the audit log.

To enable audit messages for a given rule the audit keyword is prepended to the rule.

Example

 audit /etc/shadow w,

If it is desirable to audit only a given permission on a rule then the rule can be split into two rules.

Example If audit messages are only desired for write accesses to /etc/shadow then the rule.

 /etc/shadow rw,
can be split into
audit /etc/shadow w, /etc/shadow r,

this will result in audit messages when /etc/shadow is opened for writing, but not when it is opened for just reading.

It is important to note with audit messages that they are not generated for every read or write of a file but only when a file is opened for read or write.

Audit control can be combined with owner conditional file rules to provide auditing when a user access files they own, but at this time it can not be used to audit only files they don't own.

Example

 audit owner /home/*/.ssh/** rw,


Deny rules

AppArmor 2.3 now allows for deny rules. Deny rules are used to:

  1. Annotate known rejects, so the tools don't ask about them on subsequent runs.
  2. Quiet known rejects, so that when a profile is loaded a known reject will not result in audit messages filling up the logs. If it is desirable for auditing purposes to have audit messages for a known reject then the audit keyword can be prepended to the deny rule. Alternatively the deny rule can be removed from the profile, the difference being that the tools will no longer have a way to know that a given reject is known and will prompt for it during subsequent profiling.
 Example
audit deny /foo/bar w,
  1. Carve out permissions from allow rules. Deny rules have their permissions accumulated just as allow rules do except that any the permissions in the deny set of rules are subtracted from the allow set of rules. This allows the writing of broader allow rules, and then subtracting a few known files that should not be allowed.

Example Allow access to everything in a users directory except write access to the .ssh/ files.

 deny /home/*/.ssh/** w,
 /home/*/** rw,

This use of deny rules should be used sparingly, as excessive use can make profiles harder to read, however judicious use of it can simplify profiles.

Deny rules can be combined with owner rules, to deny files owned by the user. It is not currently possible to write deny rules to deny access to files not owned by the user.
Example

 deny owner /home/*/foo w,
 audit deny owner /home/*/.ssh** w,

Alias rules

Alias rules provide an admin a way to manipulate profile path mappings to site specific layouts. They are an alternative form of path rewriting to using variables, and are done post variable resolution.

Example

 alias /home/ -> /mnt/users/
Currently no tool support, but they will not be stripped. They are not available in the tools and are hidden in tunables/alias so an admin who want to use them needs to edit tunables/alias file.



Rlimit rules

AppArmor 2.3 provides the ability for a profile to set and control an applications rlimits (man 2 setrlimit) also known as ulimits (man 3 ulimit, man 1 ulimit). By default AppArmor does not control applications rlimits, and it will only control those limits that there is a specific rule for in the confining profile.

AppArmor leverages linux's rlimits and as such does not provide an additional auditing than the would normally occur. Also AppArmor's rlmits only every reduce an applications current rlimits, they can not be used to raise the value of any limit that has been set.

The set limit's value will be inherited by a processes children and will remain even if a new profile is transitioned to, or the application becomes unconfined.

If an application transitions to a new profile, the new profile can control and further reduce the applications rlimits.

AppArmor's rlimit rules also mediate setting an applications hard limits, should it try to raise them. The application will not be able to raise its hard limits any farther than specified in the profile.

The mediation of raising hard limits is not inherited as the limit value is, so that once the application transitions to a new profile it is free to raise its limits value as if allowed by the new profile.

AppArmor's rlimit control does not affect an applications soft limits beyond ensuring that they are less than or equal to the applications hard limits.

AppArmor's hard limit rules have the general form of

 set rlimit <rlimit> <= <value>,

where <rlimit> and <value> are as described below.

<rlimit>

  • cpu - currently unsupported.
  • fsize, data, stack, core, rss, as, memlock, msgqueue:
 These rlimits take either a number in bytes, or a number with a suffix where the suffix can be
 K - kilobytes
 M - megabytes
 G - gigabytes
Example
rlimit data <= 100M,
  • nofile, locks, sigpending, nproc, rtprio
 These rlimits take a number greater or equal to 0 indicating their limit.
  • nice
 The nice rlimit takes a value between -20 and 19.

Special nproc rlimit

The nproc rlimit is special in that it is handled different than all the other rlimits. Instead of indicating the standard process rlimit it controls the maximum number of processes that can be running under the profile at any given time. Once the limit is exceeded the creation of new processes under the profile will fail until the number of currently running processes is reduced.

currently the tools can not be used to add rlimit rules to profiles. The only way to add rlimit controls to a profile is manually edit the profile with a text editor. The tools will still work with profiles containing rlimit rules and will not remove them, so it is safe to use the tools to update profiles containing them.


Set capability per profile

AppArmor 2.3 provides the ability to set an applications capabilities. This provides the ability to give non-root users administrative privileges, and as such it must be used with extreme caution.

This is the only rule that AppArmor has that can be used to raise privilege. Using it is akin to setting a program to setuid or, using fscaps.

The difference is that (like fscaps) it can control capabilities granted better than setuid, and it does not change the processes uid. Unlike fscaps and setuid instead of applying to a single program file it applies to all programs run under the profile. This allows the creation of admin style profiles, that use ix transitions for all applications that should run with the elevated privilege.

It is important to note, that AppArmor's set capabilities are not inheritable, and that as soon as an application transitions to another profile, or becomes unconfined it looses the elevated privilege granted by the profile. Once a process leaves the profile it will return to its regular capability set. Another profile may have the same or other set capabilities, which will be used.

AppArmor set capabilities cannot be learned. They can only ever be added to a profile through manual editing. The tools will work with profiles containing these rules and not strip them, so it is safe to update profiles using these rules.

To set a capability in a profile the keyword 'set' is prepended to a capability rule.

Example

 set capability dac_override,

Setting a capability also implicitly adds a capability rule allowing that capability.

To repeat the warning, these rules should not be used with out good cause as they allow giving a process some of traditional unix root privileges.

currently the tools can not be used to add rules that allow setting capabilities. To add set capabilities the profile must be manually edited with a text editor. The tools will still work with profiles containing rules setting capabilities and will not remove the rules from the profile when saving so it is safe to use the tools to update profiles containing these rules.



Variable Improvements

AppArmor 2.3 now allows for variables to be declared at the head of the file. This allows declaring of profile specific variables within the profile itself. This is useful for example to provide the base of for a chrooted path.

Example

 @{CHROOT_BASE}=/tmp/foo
 /sbin/syslog-ng {
...
# chrooted files @{CHROOT_BASE}/var/lib/*/dev/log w, @{CHROOT_BASE}/var/log/** w,
...
}

AppArmor 2.3 tools support for variables is still limited to not removing rules containing them, and rules that do contain them will not be matched by the tools to eliminate log entry questions.



Updated Log Entries

AppArmor 2.3 uses the same basic log entry format as that of AppArmor 2.1, ie. name value pair (eg. name="/foo"), however it has been extended to support the new features in 2.3.

Example

  type=APPARMOR_DENIED msg=audit(1211946303.024:499):  type=1503 operation="inode_permission" requested_mask="::r" denied_mask="::r" fsuid=1000 name="/proc/net/unix" pid=4280 profile="/usr/lib/firefox/firefox-bin///bin/netstat"

denied_mask and requested_mask

The requested_mask and denied_mask have been extended to report permissions tests based on the owner. The ownership of the permissions tested can be determined by the position of the character in the value string.

The value string is a colon ':' separated tuple with the following ordering: owner:extended owner:other. A permission will be reported in the ownership field if the file passed the ownership test. The middle position or extended owner test is unused at this time. The final position is for files that do not match the first two tests.

Example

 requested_mask="r::" means the file was read by its owner.
requested_mask="::r" means the file is owned by a user other than the processes fsuid, or the extended ownership tests.

The denied and requested masks have also been extended to report the new transition types. Cx or cx is reported for child (local) transitions, while Nx, or nx is reported for named profile transitions. When Nx is reported the name2 field contains the name of the profile that is being transitioned to.

fsuid

The fsuid field reports the fsuid of the process accessing the file. The entry format is fsuid=##.
Example

 fsuid=1000

namespace

The namespace field reports the name of the confining profiles namespace. It is only reported if profile is not from the default namespace. Since namespaces are not fully supported in AppArmor 2.3 this field should not be seen.



Determining which features the AppArmor kernel module supports

AppArmor supports an interface for determining which features are supported by the AppArmor module in the kernel.

The interface file can be found in the apparmor/matching file under securityfs. The standard mount point is at /sys/kernel/security/apparmor/matching

AppArmor 2.3 has the following value for the matching file

 pattern=aadfa audit perms=rwxamlk/ user::other

The apparmor/features file contains the versions of the features supported.