2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 10:07:12 +00:00

Rename manpage files so they start with manpage_ and add lib manpages

Signed-off-by: John Johansen <john.johansen@canonical.com>
John Johansen 2020-09-27 04:27:46 -07:00
parent bca56c0738
commit 6f257f5115
31 changed files with 1410 additions and 0 deletions

230
manpage_aa_change_hat.2.md Normal file

@ -0,0 +1,230 @@
# NAME
aa\_change\_hat - change to or from a "hat" within a AppArmor profile
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**int aa\_change\_hat (char \*subprofile, unsigned long magic\_token);**
**int aa\_change\_hatv (char \*subprofiles\[\], unsigned long magic\_token);**
**int aa\_change\_hat\_vargs (unsigned long magic\_token, ...);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
An AppArmor profile applies to an executable program; if a portion of
the program needs different access permissions than other portions,
the program can "change hats" to a different role, also known as a
subprofile.
To change into a new hat, it calls one of the family of change\_hat
functions to do so. It passes in a pointer to the _subprofile_ which it
wants to change into, and a 64bit _magic\_token_. The _magic\_token_
is used to return out of the subprofile at a later time.
The aa\_change\_hat() function allows specifying the name of a single
_subprofile_ that the application wants to change into. A pointer to the
name of the _subprofile_ is passed along with the _magic\_token_. If the
profile is not present the call will fail with the appropriate error.
The aa\_change\_hatv() function allows passing a _NULL_ terminated vector
of pointers to _subprofile_ names which will be tried in order. The
first _subprofile_ in the vector that exists will be transitioned to
and if none of the _subprofiles_ exist the call will fail with the
appropriate error.
The aa\_change\_hat\_vargs() function is a convenience wrapper for the
aa\_change\_hatv() function. After the _magic\_token_ it takes an arbitrary
number of pointers to _subprofile_ names. Similar to execl(3),
aa\_change\_hat\_vargs() assembles the list of _subprofile_ names into a
vector and calls aa\_change\_hatv().
If a program wants to return out of the current subprofile to the
original profile, it calls aa\_change\_hat() with a pointer to NULL as
the _subprofile_, and the original _magic\_token_ value. If the
_magic\_token_ does not match the original _magic\_token_ passed into the
kernel when the program entered the subprofile, the change back to the
original profile will not happen, and the current task will be killed.
If the _magic\_token_ matches the original token, then the process will
change back to the original profile.
As both read(2) and write(2) are mediated, a file must be listed in a
subprofile definition if the file is to be accessed while the process
is in a "hat".
# RETURN VALUE
On success zero is returned. On error, -1 is returned, and
errno(3) is set appropriately.
# ERRORS
- **EINVAL**
The apparmor kernel module is not loaded or the communication via the
`/proc/*/attr/current` file did not conform to protocol.
- **ENOMEM**
Insufficient kernel memory was available.
- **EPERM**
The calling application is not confined by apparmor, the specified
_subprofile_ is not a _hat profile_, the task is being ptraced and the
tracing task does not have permission to trace the specified _subprofile_ or the no\_new\_privs execution bit is
enabled.
- **ECHILD**
The application's profile has no hats defined for it.
- **ENOENT**
The specified _subprofile_ does not exist in this profile but other hats
are defined.
- **EACCES**
The specified magic token did not match, and permissions to change to
the specified _subprofile_ has been denied. This will in most situations
also result in the task being killed, to prevent brute force attacks.
# EXAMPLE
The following code examples shows simple, if contrived, uses of
aa\_change\_hat(); a typical use of aa\_change\_hat() will separate
privileged portions of a process from unprivileged portions of a process,
such as keeping unauthenticated network traffic handling separate
from authenticated network traffic handling in OpenSSH or executing
user-supplied CGI scripts in apache.
The use of random(3) is simply illustrative. Use of `/dev/urandom` is
recommended.
First, a simple high-level overview of aa\_change\_hat() use:
void foo (void) {
unsigned long magic_token;
/* get a random magic token value
from our huge entropy pool */
magic_token = random_function();
/* change into the subprofile while
* we do stuff we don't trust */
aa_change_hat("stuff_we_dont_trust", magic_token);
/* Go do stuff we don't trust -- this is all
* done in *this* process space, no separate
* fork()/exec()'s are done. */
interpret_perl_stuff(stuff_from_user);
/* now change back to our original profile */
aa_change_hat(NULL, magic_token);
}
Second, an example to show that files not listed in a subprofile ("hat")
aren't accessible after an aa\_change\_hat() call:
#include <stdlib.h>
#include <string.h>
#include <sys/apparmor.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int fd;
unsigned long tok;
char buf[10];
/* random() is a poor choice */
tok = random();
/* open /etc/passwd outside of any hat */
if ((fd=open("/etc/passwd", O_RDONLY)) < 0)
perror("Failure opening /etc/passwd");
/* confirm for ourselves that we can really read /etc/passwd */
memset(&buf, 0, 10);
if (read(fd, &buf, 10) == -1) {
perror("Failure reading /etc/passwd pre-hat");
_exit(1);
}
buf[9] = '\0';
printf("/etc/passwd: %s\n", buf);
/* change hat to the "hat" subprofile, which should not have
* read access to /etc/passwd -- even though we have a valid
* file descriptor at the time of the aa_change_hat() call. */
if (aa_change_hat("hat", tok)) {
perror("Failure changing hat -- aborting");
_exit(1);
}
/* confirm that we cannot read /etc/passwd */
lseek(fd,0,SEEK_SET);
memset(&buf, 0, 10);
if (read(fd, &buf, 10) == -1)
perror("Failure reading /etc/passwd post-hat");
buf[9] = '\0';
printf("/etc/passwd: %s\n", buf);
return 0;
}
This code example requires the following profile to be loaded with
apparmor\_parser(8):
/tmp/ch {
/etc/ld.so.cache mr,
/etc/locale/** r,
/etc/localtime r,
/usr/share/locale/** r,
/usr/share/zoneinfo/** r,
/usr/lib/locale/** mr,
/usr/lib/gconv/*.so mr,
/usr/lib/gconv/gconv-modules* mr,
/lib/ld-*.so* mrix,
/lib/libc*.so* mr,
/lib/libapparmor*.so* mr,
/dev/pts/* rw,
/tmp/ch mr,
/etc/passwd r,
^hat {
/dev/pts/* rw,
}
}
The output when run:
$ /tmp/ch
/etc/passwd: root:x:0:
Failure reading /etc/passwd post-hat: Permission denied
/etc/passwd:
$
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues). Note that
aa\_change\_hat(2) provides no memory barriers between different areas of a
program; if address space separation is required, then separate processes
should be used.
# SEE ALSO
apparmor(7), apparmor.d(5), apparmor\_parser(8), aa\_change\_profile(2),
aa\_getcon(2) and
[https://wiki.apparmor.net](https://wiki.apparmor.net).

@ -0,0 +1,180 @@
# NAME
aa\_change\_profile, aa\_change\_onexec - change a tasks profile
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**int aa\_change\_profile(const char \*profile);**
**int aa\_change\_onexec(const char \*profile);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
An AppArmor profile applies to an executable program; if a portion of
the program needs different access permissions than other portions,
the program can "change profile" to a different profile. To change into a
new profile, it can use the aa\_change\_profile() function to do so. It passes
in a pointer to the _profile_ to transition to. Confined programs wanting to
use aa\_change\_profile() need to have rules permitting changing to the named
profile. See apparmor.d(8) for details.
If a program wants to return out of the current profile to the
original profile, it may use aa\_change\_hat(2). Otherwise, the two profiles must
have rules permitting changing between the two profiles.
Open file descriptors may not be remediated after a call to aa\_change\_profile()
so the calling program must close(2) open file descriptors to ensure they
are not available after calling aa\_change\_profile(). As aa\_change\_profile()
is typically used just before execve(2), you may want to use open(2) or
fcntl(2) with close-on-exec.
The aa\_change\_onexec() function is like the aa\_change\_profile() function
except it specifies that the profile transition should take place on the
next exec instead of immediately. The delayed profile change takes
precedence over any exec transition rules within the confining profile.
Delaying the profile boundary has a couple of advantages, it removes the
need for stub transition profiles and the exec boundary is a natural security
layer where potentially sensitive memory is unmapped.
# RETURN VALUE
On success zero is returned. On error, -1 is returned, and
errno(3) is set appropriately.
# ERRORS
- **EINVAL**
The apparmor kernel module is not loaded, neither a profile nor a namespace
was specified, or the communication via the `/proc/*/attr/current` file did
not conform to protocol.
- **ENOMEM**
Insufficient kernel memory was available.
- **EPERM**
The calling application is confined by apparmor and the no\_new\_privs bit is
set.
- **EACCES**
The task does not have sufficient permissions to change its domain.
- **ENOENT**
The specified profile does not exist, or is not visible from the current
Namespace.
# EXAMPLE
The following example shows a simple, if contrived, use of
aa\_change\_profile(); a typical use of aa\_change\_profile() will
aa\_change\_profile() just before an execve(2) so that the new
child process is permanently confined.
#include <stdlib.h>
#include <string.h>
#include <sys/apparmor.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char * argv[])
{
int fd;
char buf[10];
char *execve_args[4];
printf("Before aa_change_profile():\n");
if ((fd=open("/etc/passwd", O_RDONLY)) < 0) {
perror("Failure opening /etc/passwd");
return 1;
}
/* Confirm for ourselves that we can really read /etc/passwd */
memset(&buf, 0, 10);
if (read(fd, &buf, 10) == -1) {
perror("Failure reading /etc/passwd");
return 1;
}
buf[9] = '\0';
printf("/etc/passwd: %s\n", buf);
close(fd);
printf("After aa_change_profile():\n");
/* change profile to the "i_cant_be_trusted_anymore" profile, which
* should not have read access to /etc/passwd. */
if (aa_change_profile("i_cant_be_trusted_anymore") < 0) {
perror("Failure changing profile -- aborting");
_exit(1);
}
/* confirm that we cannot read /etc/passwd */
execve_args[0] = "/usr/bin/head";
execve_args[1] = "-1";
execve_args[2] = "/etc/passwd";
execve_args[3] = NULL;
execve("/usr/bin/head", execve_args, NULL);
perror("execve");
_exit(1);
}
This code example requires a profile similar to the following to be loaded
with apparmor\_parser(8):
profile i_cant_be_trusted_anymore {
/etc/ld.so.cache mr,
/lib/ld-*.so* mrix,
/lib/libc*.so* mr,
/usr/bin/head ix,
}
The output when run:
$ /tmp/change_p
Before aa_change_profile():
/etc/passwd: root:x:0:
After aa_change_profile():
/usr/bin/head: cannot open `/etc/passwd' for reading: Permission denied
$
If /tmp/change\_p is to be confined as well, then the following profile can be
used (in addition to the one for 'i\_cant\_be\_trusted\_anymore', above):
# Confine change_p to be able to read /etc/passwd and aa_change_profile()
# to the 'i_cant_be_trusted_anymore' profile.
/tmp/change_p {
/etc/ld.so.cache mr,
/lib/ld-*.so* mrix,
/lib/libc*.so* mr,
/etc/passwd r,
# Needed for aa_change_profile()
/usr/lib/libapparmor*.so* mr,
/proc/[0-9]*/attr/current w,
change_profile -> i_cant_be_trusted_anymore,
}
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues). Note that using
aa\_change\_profile(2) without execve(2) provides no memory barriers between
different areas of a program; if address space separation is required, then
separate processes should be used.
# SEE ALSO
apparmor(7), apparmor.d(5), apparmor\_parser(8), aa\_change\_hat(2) and
[https://wiki.apparmor.net](https://wiki.apparmor.net).

157
manpage_aa_features.3.md Normal file

@ -0,0 +1,157 @@
# NAME
aa\_features - an opaque object representing a set of AppArmor kernel features
aa\_features\_new - create a new aa\_features object based on a path
aa\_features\_new\_from\_string - create a new aa\_features object based on a string
aa\_features\_new\_from\_kernel - create a new aa\_features object based on the current kernel
aa\_features\_ref - increments the ref count of an aa\_features object
aa\_features\_unref - decrements the ref count and frees the aa\_features object when 0
aa\_features\_write\_to\_file - write a string representation of an aa\_features object to a file
aa\_features\_is\_equal - equality test for two aa\_features objects
aa\_features\_supports - provides aa\_features object support status
aa\_features\_id - provides unique identifier for an aa\_features object
aa\_features\_value - the value associated with a given feature.
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**typedef struct aa\_features aa\_features;**
**int aa\_features\_new(aa\_features \*\*features, int dirfd, const char \*path);**
**int aa\_features\_new\_from\_file(aa\_features \*\*features, int fd);**
**int aa\_features\_new\_from\_string(aa\_features \*\*features, const char \*string, size\_t size);**
**int aa\_features\_new\_from\_kernel(aa\_features \*\*features);**
**aa\_features \*aa\_features\_ref(aa\_features \*features);**
**void aa\_features\_unref(aa\_features \*features);**
**int aa\_features\_write\_to\_file(aa\_features \*features, int dirfd, const char \*path);**
**bool aa\_features\_is\_equal(aa\_features \*features1, aa\_features \*features2);**
**bool aa\_features\_supports(aa\_features \*features, const char \*str);**
**char \*aa\_features\_id(aa\_features \*features);**
**char \*aa\_features\_value(aa\_features \*features, const char \*str, size\_t \*len);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
The _aa\_features_ object contains information about the AppArmor features
supported by a kernel. The feature support information is based upon the files
AppArmor represents in securityfs, which is typically found at
/sys/kernel/security/apparmor/features/. That information may be parsed and
turned into a string or flat file in order to represent a set of features of a
kernel that is not currently running.
The aa\_features\_new() function creates an _aa\_features_ object based upon a
directory file descriptor and path. The _path_ can point to a file or
directory. See the openat(2) man page for examples of _dirfd_ and _path_. The
allocated _features_ object must be freed using aa\_features\_unref().
The aa\_features\_new\_from\_file() function is similar except that it
accepts an open file as the argument. The allocated _features_ object
must be freed using aa\_features\_unref().
The aa\_features\_new\_from\_string() function is similar except that it accepts a
NUL-terminated string representation of the AppArmor features as the _string_
argument. The length of the features string, not counting the NUL-terminator,
must be specified as the _size_ argument. The allocated _features_ object
must be freed using aa\_features\_unref().
The aa\_features\_new\_from\_kernel() function creates an _aa\_features_ object
from the current running kernel. The allocated _features_ object must be freed
using aa\_features\_unref().
aa\_features\_ref() increments the reference count on the _features_ object.
aa\_features\_unref() decrements the reference count on the _features_ object
and releases all corresponding resources when the reference count reaches zero.
The aa\_features\_write\_to\_file() function writes a string representation of the
_features_ object to the file specified by the _dirfd_ and _path_
combination.
aa\_features\_is\_equal() can be used to detect if the _features1_ and
_features2_ objects are equal. The definition of equality is private to
libapparmor and may be changed in ways that do not break backward
compatibility.
The aa\_features\_supports() function can be used to query the _features_ object
to determine if a feature is supported. The _str_ argument should be equal to
the path, relative to the "apparmor/features/" directory of securityfs, of the
feature to query. For example, to test if policy version 6 is supported, _str_
would be "policy/versions/v6".
The aa\_features\_id() function returns a string representation of an
identifier that can be used to uniquely identify an _aa\_features_ object.
The mechanism for generating the string representation is internal to
libapparmor and subject to change but an example implementation is
applying a hash function to the features string.
# RETURN VALUE
The aa\_features\_new() family of functions return 0 on success and _\*features_
will point to an _aa\_features_ object that must be freed by
aa\_features\_unref(). -1 is returned on error, with errno set appropriately, and
_\*features_ will be set to NULL.
aa\_features\_ref() returns the value of _features_.
aa\_features\_write\_to\_file() returns 0 on success. -1 is returned on error, with
errno set appropriately.
aa\_features\_is\_equal() returns true if _features1_ and _features2_ are equal
and false if they are not equal.
aa\_features\_supports() returns true if the feature represented by _str_ is
supported and false if it is not supported.
aa\_features\_id() returns a string identifying _features_ which must be
freed by the caller. NULL is returned on error, with errno set
appropriately.
aa\_features\_value() returns a null terminated string with is
associated length which must be freed by the caller. NULL is returned
on error, with errno set to ENOENT if the feature was not found,
ENODIR if the specified feature does not resolve to a leaf feature.
# ERRORS
The errno value will be set according to the underlying error in the
_aa\_features_ family of functions that return -1 or NULL on error.
# NOTES
The aa\_features\_id() function can be found in libapparmor version
2.13. All the other aa\_feature functions described above are present
in libapparmor version 2.10.
aa\_features\_unref() saves the value of errno when called and restores errno
before exiting in libapparmor version 2.12 and newer.
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues).
# SEE ALSO
openat(2) and [https://wiki.apparmor.net](https://wiki.apparmor.net).

@ -0,0 +1,93 @@
# NAME
aa\_is\_enabled - determine if apparmor is available
aa\_find\_mountpoint - find where the apparmor interface filesystem is mounted
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**int aa\_is\_enabled(void);**
**int aa\_find\_mountpoint(char \*\*mnt);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
The aa\_is\_enabled function returns true (1) if apparmor is enabled.
If it isn't it sets the errno(3) to reflect the reason it is not
enabled and returns 0.
The aa\_find\_mountpoint function finds where the apparmor filesystem is mounted
on the system, and returns a string containing the mount path. It is the
caller's responsibility to free(3) the returned path.
# RETURN VALUE
**aa\_is\_enabled**
On success 1 is returned. On error, 0 is returned, and errno(3) is set
appropriately.
**aa\_find\_mountpoint**
On success zero is returned. On error, -1 is returned, and errno(3) is set
appropriately.
# ERRORS
**aa\_is\_enabled**
- **ENOSYS**
AppArmor extensions to the system are not available.
- **ECANCELED**
AppArmor is available on the system but has been disabled at boot.
- **ENOENT**
AppArmor is available (and maybe even enforcing policy) but the interface is
not available.
- **ENOMEM**
Insufficient memory was available.
- **EPERM**
Did not have sufficient permissions to determine if AppArmor is enabled.
- **EACCES**
Did not have sufficient permissions to determine if AppArmor is enabled.
- **EBUSY**
AppArmor is enabled but does not have access to shared interfaces, and
only private interfaces are available.
**aa\_find\_mountpoint**
- **ENOMEM**
Insufficient memory was available.
- **EACCES**
Access to the required paths was denied.
- **ENOENT**
The apparmor filesystem mount could not be found
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues).
# SEE ALSO
apparmor(7), apparmor.d(5), apparmor\_parser(8), and
[https://wiki.apparmor.net](https://wiki.apparmor.net).

109
manpage_aa_getcon.2.md Normal file

@ -0,0 +1,109 @@
# NAME
aa\_getprocattr\_raw, aa\_getprocattr - read and parse procattr data
aa\_getcon, aa\_gettaskcon - get task confinement information
aa\_getpeercon - get the confinement of a socket's other end (peer)
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**int aa\_getprocattr\_raw(pid\_t tid, const char \*attr, char \*buf, int len, char \*\*mode);**
**int aa\_getprocattr(pid\_t tid, const char \*attr, char \*\*label, char \*\*mode);**
**int aa\_gettaskcon(pid\_t target, char \*\*label, char \*\*mode);**
**int aa\_getcon(char \*\*label, char \*\*mode);**
**int aa\_getpeercon\_raw(int fd, char \*buf, int \*len, char \*\*mode);**
**int aa\_getpeercon(int fd, char \*\*label, char \*\*mode);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
The aa\_getcon function gets the current AppArmor confinement context for the
current task. The confinement context consists of a label and a mode. The label
is usually just the name of the AppArmor profile restricting the task, but it
may include the profile namespace or in some cases a set of profile names
(known as a stack of profiles). The mode is a string that describes how the
kernel is enforcing the policy defined in the profile. Profiles loaded in
"enforce" mode will result in enforcement of the policy defined in the profile
as well as reporting policy violation attempts. Profiles in "complain" mode
will not enforce policy but instead report policy violation attempts.
Some examples of possible returned \*label strings are "unconfined", "/sbin/dhclient",
and "Firefox". The string can consist of any non-NUL characters but it will be
NUL-terminated. The \*label string must be freed using free().
The possible \*mode strings are "enforce" and "complain". Additionally, \*mode may
be NULL when \*label is "unconfined". **The \*mode string must not be freed**. The
\*label and \*mode strings come from a single buffer allocation and are separated
by a NUL character.
The aa\_gettaskcon function is like the aa\_getcon function except it will work
for any arbitrary task in the system.
The aa\_getpeercon function is similar to that of aa\_gettaskcon except that
it returns the confinement information for task on the other end of a socket
connection.
The aa\_getpeercon\_raw function is the backend for the aa\_getpeercon function
and does not handle buffer allocation.
The aa\_getprocattr function is the backend for the aa\_getcon and aa\_gettaskcon
functions and handles the reading and parsing of the confinement data from
different arbitrary attr files and returns the processed results in
an allocated buffer.
The aa\_getprocattr\_raw() is the backend for the aa\_getprocattr function and
does not handle buffer allocation.
# RETURN VALUE
On success size of data placed in the buffer is returned, this includes the
mode if present and any terminating characters. On error, -1 is returned, and
errno(3) is set appropriately.
# ERRORS
- **EINVAL**
The apparmor kernel module is not loaded or the communication via the
`/proc/*/attr/file` did not conform to protocol.
- **ENOMEM**
Insufficient kernel memory was available.
- **EACCES**
Access to the specified _file/task_ was denied.
- **ENOENT**
The specified _file/task_ does not exist or is not visible.
- **ERANGE**
The confinement data is too large to fit in the supplied buffer.
# NOTES
If aa\_getpeercon\_raw returns -1 and errno is ERANGE, the value of \*len can be
used to reallocate buf so that it is sufficiently large enough to store the
confinement data.
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues).
# SEE ALSO
apparmor(7), apparmor.d(5), apparmor\_parser(8), aa\_change\_profile(2),
aa\_splitcon(3) and [https://wiki.apparmor.net](https://wiki.apparmor.net).

@ -0,0 +1,141 @@
# NAME
aa\_kernel\_interface - an opaque object representing the AppArmor kernel interface for policy loading, replacing, and removing
aa\_kernel\_interface\_new - create a new aa\_kernel\_interface object from an optional path
aa\_kernel\_interface\_ref - increments the ref count of an aa\_kernel\_interface object
aa\_kernel\_interface\_unref - decrements the ref count and frees the aa\_kernel\_interface object when 0
aa\_kernel\_interface\_load\_policy - load a policy from a buffer into the kernel
aa\_kernel\_interface\_load\_policy\_from\_file - load a policy from a file into the kernel
aa\_kernel\_interface\_load\_policy\_from\_fd - load a policy from a file descriptor into the kernel
aa\_kernel\_interface\_replace\_policy - replace a policy in the kernel with a policy from a buffer
aa\_kernel\_interface\_replace\_policy\_from\_file - replace a policy in the kernel with a policy from a file
aa\_kernel\_interface\_replace\_policy\_from\_fd - replace a policy in the kernel with a policy from a file descriptor
aa\_kernel\_interface\_remove\_policy - remove a policy from the kernel
aa\_kernel\_interface\_write\_policy - write a policy to a file descriptor
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**typedef struct aa\_kernel\_interface aa\_kernel\_interface;**
**int aa\_kernel\_interface\_new(aa\_kernel\_interface \*\*kernel\_interface, aa\_features \*kernel\_features, const char \*apparmorfs);**
**aa\_kernel\_interface \*aa\_kernel\_interface\_ref(aa\_kernel\_interface \*kernel\_interface);**
**void aa\_kernel\_interface\_unref(aa\_kernel\_interface \*kernel\_interface);**
**int aa\_kernel\_interface\_load\_policy(aa\_kernel\_interface \*kernel\_interface, const char \*buffer, size\_t size);**
**int aa\_kernel\_interface\_load\_policy\_from\_file(aa\_kernel\_interface \*kernel\_interface, int dirfd, const char \*path);**
**int aa\_kernel\_interface\_load\_policy\_from\_fd(aa\_kernel\_interface \*kernel\_interface, int fd);**
**int aa\_kernel\_interface\_replace\_policy(aa\_kernel\_interface \*kernel\_interface, const char \*buffer, size\_t size);**
**int aa\_kernel\_interface\_replace\_policy\_from\_file(aa\_kernel\_interface \*kernel\_interface, int dirfd, const char \*path);**
**int aa\_kernel\_interface\_replace\_policy\_from\_fd(aa\_kernel\_interface \*kernel\_interface, int fd);**
**int aa\_kernel\_interface\_remove\_policy(aa\_kernel\_interface \*kernel\_interface, const char \*fqname);**
**int aa\_kernel\_interface\_write\_policy(int fd, const char \*buffer, size\_t size);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
The _aa\_kernel\_interface_ object contains information about the AppArmor
kernel interface for policy loading, replacing, and removing.
The aa\_kernel\_interface\_new() function creates an _aa\_kernel\_interface_ object
based on an optional _aa\_features_ object and an optional path to the apparmor
directory of securityfs, which is typically found at
"/sys/kernel/security/apparmor/". If _kernel\_features_ is NULL, then the
features of the current kernel are used. When specifying a valid
_kernel\_features_ object, it must be compatible with the features of the
currently running kernel. If _apparmorfs_ is NULL, then the default location
is used. The allocated _kernel\_interface_ object must be freed using
aa\_kernel\_interface\_unref().
aa\_kernel\_interface\_ref() increments the reference count on the
_kernel\_interface_ object.
aa\_kernel\_interface\_unref() decrements the reference count on the
_kernel\_interface_ object and releases all corresponding resources when the
reference count reaches zero.
The aa\_kernel\_interface\_load() family of functions load a policy into the
kernel. The operation will fail if a policy of the same name is already loaded.
Use the aa\_kernel\_interface\_replace() family of functions if you wish to
replace a previously loaded policy with a new policy of the same name. The
aa\_kernel\_interface\_replace() functions can also be used to load a policy that
does not correspond to a previously loaded policy.
When loading or replacing from a buffer, the _buffer_ will contain binary
data. The _size_ argument must specify the size of the _buffer_ argument.
When loading or replacing from a file, the _dirfd_ and _path_ combination are
used to specify the location of the file. See the openat(2) man page for
examples of _dirfd_ and _path_.
It is also possible to load or replace from a file descriptor specified by the
_fd_ argument. The file must be open for reading and the file offset must be
set appropriately.
The aa\_kernel\_interface\_remove\_policy() function can be used to unload a
previously loaded policy. The fully qualified policy name must be specified
with the _fqname_ argument. The operation will fail if a policy matching
_fqname_ is not found.
The aa\_kernel\_interface\_write\_policy() function allows for a policy, which is
stored in _buffer_ and consists of _size_ bytes, to be written to a file
descriptor. The _fd_ must be open for writing and the file offset must be set
appropriately.
# RETURN VALUE
The aa\_kernel\_interface\_new() function returns 0 on success and
_\*kernel\_interface_ will point to an _aa\_kernel\_interface_ object that must
be freed by aa\_kernel\_interface\_unref(). -1 is returned on error, with errno
set appropriately, and _\*kernel\_interface_ will be set to NULL.
aa\_kernel\_interface\_ref() returns the value of _kernel\_interface_.
The aa\_kernel\_interface\_load() family of functions, the
aa\_kernel\_interface\_replace() family of functions,
aa\_kernel\_interface\_remove(), and aa\_kernel\_interface\_write\_policy()
return 0 on success. -1 is returned on error, with errno set appropriately.
# ERRORS
The errno value will be set according to the underlying error in the
_aa\_kernel\_interface_ family of functions that return -1 on error.
# NOTES
All aa\_kernel\_interface functions described above are present in libapparmor
version 2.10 and newer.
aa\_kernel\_interface\_unref() saves the value of errno when called and restores
errno before exiting in libapparmor version 2.12 and newer.
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues).
# SEE ALSO
aa\_features(3), openat(2) and [https://wiki.apparmor.net](https://wiki.apparmor.net).

@ -0,0 +1,155 @@
# NAME
aa\_policy\_cache - an opaque object representing an AppArmor policy cache
aa\_policy\_cache\_new - create a new aa\_policy\_cache object from a path
aa\_policy\_cache\_ref - increments the ref count of an aa\_policy\_cache object
aa\_policy\_cache\_unref - decrements the ref count and frees the aa\_policy\_cache object when 0
aa\_policy\_cache\_remove - removes all policy cache files under a path
aa\_policy\_cache\_replace\_all - performs a kernel policy replacement of all cached policies
aa\_policy\_cache\_dir\_path - returns the path to the aa\_policy\_cache directory
aa\_policy\_cache\_dir\_path\_preview - returns a preview of the path to the aa\_policy\_cache directory without an existing aa\_policy\_cache object
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**typedef struct aa\_policy\_cache aa\_policy\_cache;**
**int aa\_policy\_cache\_new(aa\_policy\_cache \*\*policy\_cache, aa\_features \*kernel\_features, int dirfd, const char \*path, uint16\_t max\_caches);**
**int aa\_policy\_cache\_add\_ro\_dir(aa\_policy\_cache \*policy\_cache, int dirfd, const char \*path);**
**aa\_policy\_cache \*aa\_policy\_cache\_ref(aa\_policy\_cache \*policy\_cache);**
**void aa\_policy\_cache\_unref(aa\_policy\_cache \*policy\_cache);**
**int aa\_policy\_cache\_remove(int dirfd, const char \*path);**
**int aa\_policy\_cache\_replace\_all(aa\_policy\_cache \*policy\_cache, aa\_kernel\_interface \*kernel\_interface);**
**char \*aa\_policy\_cache\_dir\_path(aa\_policy\_cache \*policy\_cache, int level);**
**char \*aa\_policy\_cache\_dir\_path\_preview(aa\_features \*kernel\_features, int dirfd, const char \*path);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
The _aa\_policy\_cache_ object contains information about a set of AppArmor
policy cache files. The policy cache files are the binary representation of a
human-readable AppArmor profile. The binary representation is the form that is
loaded into the kernel.
The aa\_policy\_cache\_new() function creates an _aa\_policy\_cache_
object based upon a directory file descriptor and path. See the
openat(2) man page for examples of _dirfd_ and _path_. The _path_
must point to a directory and it will be used as the basis for the
location of policy cache files. See _aa\_policy\_cache\_dir\_path_ to
find out which directory will be used to store the binary policy cache
files. If additional overlay cache directories are used (see
_aa\_policy\_cache\_add\_ro\_dir_) the directory specified in
_aa\_policy\_cache\_new_ is the first directory searched and is the
writable overlay. If _kernel\_features_ is NULL, then the features of
the current kernel are used. When specifying a valid
_kernel\_features_ object, it must be compatible with the features
of the kernel of interest. The value of _max\_caches_ should be equal
to the number of caches that should be allowed before old caches are
automatically reaped. The definition of what is considered to be an
old cache is private to libapparmor. Specifying 0 means that no new
caches should be created and only existing, valid caches may be used.
Specifying UINT16\_MAX means that a new cache may be created and that
the reaping of old caches is disabled. The allocated
_aa\_policy\_cache_ object must be freed using aa\_policy\_cache\_unref().
The aa\_policy\_cache\_add\_ro\_dir() function adds an existing cache directory
to the policy cache, as a readonly layer under the primary directory
the cache was created with. When the cache is searched for an existing
cache file the primary directory will be searched and then the readonly
directories in the order that they were added to the policy cache.
This allows the policy cache to be seeded with precompiled policy
that can be updated by overlaying the read only cache file with one
written to the primary cache dir.
aa\_policy\_cache\_ref() increments the reference count on the _policy\_cache_
object.
aa\_policy\_cache\_unref() decrements the reference count on the _policy\_cache_
object and releases all corresponding resources when the reference count
reaches zero.
The aa\_policy\_cache\_remove() function deletes all of the policy cache files
based upon a directory file descriptor and path. The _path_ must point to a
directory. See the openat(2) man page for examples of _dirfd_ and _path_.
The aa\_policy\_cache\_replace\_all() function can be used to perform a policy
replacement of all of the cache policies in the cache directory represented by
the _policy\_cache_ object. If _kernel\_interface_ is NULL, then the current
kernel interface is used. When specifying a valid _kernel\_interface_ object,
it must be the interface of the currently running kernel.
The aa\_policy\_cache\_dir\_path() function provides the path to the cache
directory for a _policy\_cache_ object at _level_ in the policy cache
overlay of cache directories. A _level_ of 0 will always be present
and is the first directory to search in an overlay of cache
directories, and will also be the writable cache directory
layer. Binary policy cache files will be located in the directory
returned by this function.
The aa\_policy\_cache\_dir\_levels() function provides access to the number
of directories that are being overlayed to create the policy cache.
# RETURN VALUE
The aa\_policy\_cache\_new() function returns 0 on success and _\*policy\_cache_
will point to an _aa\_policy\_cache_ object that must be freed by
aa\_policy\_cache\_unref(). -1 is returned on error, with errno set appropriately,
and _\*policy\_cache_ will be set to NULL.
aa\_policy\_cache\_ref() returns the value of _policy\_cache_.
aa\_policy\_cache\_remove() and aa\_policy\_cache\_replace\_all() return 0 on success.
\-1 is returned on error, with errno set appropriately.
aa\_policy\_cache\_dir\_path() returns a path string which must be freed by the
caller. NULL is returned on error, with errno set appropriately.
aa\_policy\_cache\_dir\_levels() returns a number indicating the number of
directory levels there are associated with the _policy\_cache_.
aa\_policy\_cache\_dir\_path\_preview() is the same as
aa\_policy\_cache\_dir\_path() except that it doesn't require an existing
_aa\_policy\_cache_ object. This is useful if the calling program cannot
create an _aa\_policy\_cache_ object due to lack of privileges needed to
create the cache directory.
# ERRORS
The errno value will be set according to the underlying error in the
_aa\_policy\_cache_ family of functions that return -1 or NULL on error.
# NOTES
All aa\_policy\_cache functions described above, except for the
aa\_policy\_cache\_dir\_path() function was added in libapparmor version
2.13. All the other aa\_policy\_cache functions described above are
present in libapparmor version 2.10.
aa\_policy\_cache\_unref() saves the value of errno when called and restores errno
before exiting in libapparmor version 2.12 and newer.
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues).
# SEE ALSO
aa\_features(3), aa\_kernel\_interface(3), openat(2) and
[https://wiki.apparmor.net](https://wiki.apparmor.net).

104
manpage_aa_query_label.2.md Normal file

@ -0,0 +1,104 @@
# NAME
aa\_query\_label - query access permission associated with a label
aa\_query\_file\_path, aa\_query\_file\_path\_len - query access permissions of a file path
aa\_query\_link\_path, aa\_query\_link\_path\_len - query access permissions of a link path
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**int aa\_query\_label(uint32\_t mask, char \*query, size\_t size, int \*allowed, int \*audited);**
**int aa\_query\_file\_path(uint32\_t mask, const char \*label, size\_t label\_len, const char \*path, int \*allowed, int \*audited);**
**int aa\_query\_file\_path\_len(uint32\_t mask, const char \*label, size\_t label\_len, const char \*path, size\_t path\_len, int \*allowed, int \*audited);**
**int aa\_query\_link\_path(const char \*label, const char \*target, const char \*link, int \*allowed, int \*audited);**
**int aa\_query\_link\_path\_len(const char \*label, size\_t label\_len, const char \*target, size\_t target\_len, const char \*link, size\_t link\_len, int \*allowed, int \*audited);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
The **aa\_query\_label** function fetches the current permissions granted by the
specified _label_ in the _query_ string.
The query is a raw binary formatted query, containing the label and
permission query to make. The returned _allowed_ and _audited_ values are
interpreted boolean values, simply stating whether the query is allowed and
if it is audited.
The mask of the query string is a bit mask of permissions to query and is
class type dependent (see **AA\_CLASS\_xxx** entries in _sys/apparmor.h_).
The format of the query string is also dependent on the **AA\_CLASS** and as
such the **aa\_query\_xxx** helper functions should usually be used instead
of directly using **aa\_query\_label**. If directly using the interface the
_query_ string is required to have a header of **AA\_QUERY\_CMD\_LABEL\_SIZE**
that will be used by **aa\_query\_label**.
The **aa\_query\_file\_path** and **aa\_query\_file\_path\_len** functions are helper
function that assemble a properly formatted file path query for the
**aa\_query\_label** function. The _label_ is a valid apparmor label as
returned by _aa\_splitcon_ with _label\_len_ being the length of the _label_.
The _path_ is any valid filesystem path to query permissions for. For the
**aa\_query\_file\_path\_len** variant the _path\_len_ parameter specifies the
number of bytes in the _path_ to use as part of the query.
The **aa\_query\_link\_path** and **aa\_query\_link\_path\_len** functions are helper
functions that assemble a properly formatted link path query for the
**aa\_query\_label** function. The _link\_len_ and _target\_len_ parameters
specify the number of bytes in the _link_ and _target_ to use as part of
the query.
# RETURN VALUE
On success 0 is returned, and the _allowed_ and _audited_ parameters
contain a boolean value of 0 not allowed/audited or 1 allowed/audited. On
error, -1 is returned, and errno(3) is set appropriately.
# ERRORS
- **EINVAL**
The requested _mask_ is empty.
The _size_ of the query is less than the query **AA\_QUERY\_CMD\_LABEL\_SIZE**
The apparmor kernel module is not loaded or the kernel interface access
interface is not available
- **ENOMEM**
Insufficient memory was available.
- **EACCES**
Access to the specified _label_ or query interface was denied.
- **ENOENT**
The specified _label_ does not exist or is not visible.
- **ERANGE**
The confinement data is too large to fit in the supplied buffer.
# NOTES
The label permissions returned are only valid for the time of the
query and can change at any point in the future.
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues).
# SEE ALSO
apparmor(7), apparmor.d(5), apparmor\_parser(8), aa\_getcon(2), aa\_splitcon(3)
and [https://wiki.apparmor.net](https://wiki.apparmor.net).

48
manpage_aa_splitcon.3.md Normal file

@ -0,0 +1,48 @@
# NAME
aa\_splitcon - split the confinement context into a label and mode
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**char \*aa\_splitcon(char \*con, char \*\*mode);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
The aa\_splitcon() function splits a confinement context into separate label
and mode strings. The @con string is modified so that the label portion is NUL
terminated. The enforcement mode is also NUL terminated and the parenthesis
surrounding the mode are removed. If @mode is non-NULL, it will point to the
first character in the enforcement mode string on success.
The Linux kernel's /proc/<PID>/attr/current interface appends a
trailing newline character to AppArmor contexts that are read from that file.
If @con contains a single trailing newline character, it will be stripped by
aa\_splitcon() prior to all other processing.
# RETURN VALUE
Returns a pointer to the first character in the label string. NULL is returned
on error.
# EXAMPLE
Context Label Mode
----------------------------- ------------------ -------
unconfined unconfined NULL
unconfined\n unconfined NULL
/bin/ping (enforce) /bin/ping enforce
/bin/ping (enforce)\n /bin/ping enforce
/usr/sbin/rsyslogd (complain) /usr/sbin/rsyslogd complain
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues).
# SEE ALSO
aa\_getcon(2) and [https://wiki.apparmor.net](https://wiki.apparmor.net).

@ -0,0 +1,193 @@
# NAME
aa\_stack\_profile, aa\_stack\_onexec - combine multiple profiles to confine a task
# SYNOPSIS
**#include &lt;sys/apparmor.h>**
**int aa\_stack\_profile(const char \*profile);**
**int aa\_stack\_onexec(const char \*profile);**
Link with **-lapparmor** when compiling.
# DESCRIPTION
AppArmor supports stacking two or more profiles when confining a task. The
result is an intersection of all profiles which are stacked. Stacking profiles
together is desirable when wanting to ensure that confinement will never become
more permissive. When changing between two profiles, as performed with
aa\_change\_profile(2), there is always the possibility that the new profile is
more permissive than the old profile but that possibility is eliminated when
using aa\_stack\_profile().
To stack a profile with the current confinement context, a task can use the
aa\_stack\_profile() function. The _profile_ parameter is a NUL-terminated
string indicating a profile name that should be stacked with the current
confinement.
Calling aa\_stack\_profile("profile\_a") while unconfined is equivalent to calling
aa\_change\_profile("profile\_a") since the intersection of unconfined and
"profile\_a" is "profile\_a". Calling aa\_stack\_profile("profile\_b") while
confined by "profile\_a" results in the task's confinement to be the
intersection of "profile\_a" and "profile\_b". The resulting confinement context
will be represented as "profile\_a//&profile\_b" in audit log messages, the
return value of aa\_getcon(2), etc.
Confined programs wanting to use aa\_stack\_profile() need to have rules
permitting stacking the named profile. See apparmor.d(8) for details.
Open file descriptors may not be remediated after a call to aa\_stack\_profile()
so the calling program must close(2) open file descriptors to ensure they
are not available after calling aa\_stack\_profile().
The aa\_stack\_onexec() function is like the aa\_stack\_profile() function
except it specifies that the stacking should take place on the next exec
instead of immediately. The delayed profile change takes precedence over any
exec transition rules within the confining profile. Delaying the stacking
boundary has a couple of advantages, it removes the need for stub transition
profiles and the exec boundary is a natural security layer where potentially
sensitive memory is unmapped.
# RETURN VALUE
On success zero is returned. On error, -1 is returned, and
errno(3) is set appropriately.
# ERRORS
- **EINVAL**
AppArmor is not loaded, neither a profile nor a namespace was specified,
or the communication via the `/proc/*/attr/current` file did not conform
to protocol.
- **ENOMEM**
Insufficient kernel memory was available.
- **ENOENT**
The specified profile does not exist, or is not visible from the current
namespace.
# NOTES
Using aa\_stack\_profile() and related libapparmor functions are the only way to
ensure compatibility between varying kernel versions. However, there may be
some situations where libapparmor is not available and directly interacting
with the AppArmor filesystem is required to stack a profile.
To immediately stack a profile named "profile\_a", as performed with
aa\_stack\_profile("profile\_a"), the equivalent of this shell command can be
used:
$ echo -n "stackprofile profile_a" > /proc/self/attr/current
To stack a profile named "profile\_a" at the next exec, as performed with
aa\_stack\_onexec("profile\_a"), the equivalent of this shell command can be used:
$ echo -n "stackexec profile_a" > /proc/self/attr/exec
These raw AppArmor filesystem operations must only be used when using
libapparmor is not a viable option.
# EXAMPLE
The following example shows a simple, if contrived, use of
aa\_stack\_profile().
#include <stdlib.h>
#include <string.h>
#include <sys/apparmor.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
static void read_passwd()
{
int fd;
char buf[10];
if ((fd=open("/etc/passwd", O_RDONLY)) < 0) {
perror("Failure opening /etc/passwd");
_exit(1);
}
/* Verify that we can read /etc/passwd */
memset(&buf, 0, 10);
if (read(fd, &buf, 10) == -1) {
perror("Failure reading /etc/passwd");
_exit(1);
}
buf[9] = '\0';
printf("/etc/passwd: %s\n", buf);
close(fd);
}
int main(int argc, char * argv[])
{
printf("Before aa_stack_profile():\n");
read_passwd();
/* stack the "i_cant_be_trusted_anymore" profile, which
* should not have read access to /etc/passwd. */
if (aa_stack_profile("i_cant_be_trusted_anymore") < 0) {
perror("Failure changing profile -- aborting");
_exit(1);
}
printf("After aa_stack_profile():\n");
read_passwd();
_exit(0);
}
This code example requires a profile similar to the following to be loaded
with apparmor\_parser(8):
# Confine stack_p to be able to read /etc/passwd and aa_stack_profile()
# to the 'i_cant_be_trusted_anymore' profile.
/tmp/stack_p {
/etc/ld.so.cache mr,
/lib/ld-*.so* mrix,
/lib/libc*.so* mr,
/etc/passwd r,
# Needed for aa_stack_profile()
/usr/lib/libapparmor*.so* mr,
/proc/[0-9]*/attr/current w,
}
As well as the profile to stack:
profile i_cant_be_trusted_anymore {
/etc/ld.so.cache mr,
/lib/ld-*.so* mrix,
/lib/libc*.so* mr,
}
The output when run:
$ /tmp/stack_p
Before aa_stack_profile():
/etc/passwd: root:x:0:
After aa_stack_profile():
Failure opening /etc/passwd: Permission denied
$
# BUGS
None known. If you find any, please report them at
[https://gitlab.com/apparmor/apparmor/-/issues](https://gitlab.com/apparmor/apparmor/-/issues). Note that using
aa\_stack\_profile(2) without execve(2) provides no memory barriers between
different areas of a program; if address space separation is required, then
separate processes should be used.
# SEE ALSO
apparmor(7), apparmor.d(5), apparmor\_parser(8), aa\_change\_profile(2),
aa\_getcon(2) and [https://wiki.apparmor.net](https://wiki.apparmor.net).