AA_CHANGE_PROFILE(2) AppArmor AA_CHANGE_PROFILE(2)
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. Transitioning to another profile via aa_change_profile() is permanent and the
process is not permitted to transition back to the original profile. 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 should use aa_change_hat(2) instead.
Open file descriptors are not 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 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.
EACCES
The task does not have sufficient permissions to change its domain.
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():
");
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] = '