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>
parent
bca56c0738
commit
6f257f5115
230
manpage_aa_change_hat.2.md
Normal file
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 <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).
|
180
manpage_aa_change_profile.2.md
Normal file
180
manpage_aa_change_profile.2.md
Normal file
@ -0,0 +1,180 @@
|
||||
# NAME
|
||||
|
||||
aa\_change\_profile, aa\_change\_onexec - change a tasks profile
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
**#include <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
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 <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).
|
93
manpage_aa_find_mountpoint.2.md
Normal file
93
manpage_aa_find_mountpoint.2.md
Normal file
@ -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 <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
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 <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).
|
141
manpage_aa_kernel_interface.3.md
Normal file
141
manpage_aa_kernel_interface.3.md
Normal file
@ -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 <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).
|
155
manpage_aa_policy_cache.3.md
Normal file
155
manpage_aa_policy_cache.3.md
Normal file
@ -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 <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
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 <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
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 <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).
|
193
manpage_aa_stack_profile.2.md
Normal file
193
manpage_aa_stack_profile.2.md
Normal file
@ -0,0 +1,193 @@
|
||||
# NAME
|
||||
|
||||
aa\_stack\_profile, aa\_stack\_onexec - combine multiple profiles to confine a task
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
**#include <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).
|
Loading…
x
Reference in New Issue
Block a user