1
# This publication is intellectual property of Canonical Ltd. Its contents
2
# can be duplicated, either in part or in whole, provided that a copyright
3
# label is visibly located on each copy.
5
# All information found in this book has been compiled with utmost
6
# attention to detail. However, this does not guarantee complete accuracy.
7
# Neither Canonical Ltd, the authors, nor the translators shall be held
8
# liable for possible errors or the consequences thereof.
10
# Many of the software and hardware descriptions cited in this book
11
# are registered trademarks. All trade names are subject to copyright
12
# restrictions and may be registered trade marks. Canonical Ltd.
13
# essentially adhere to the manufacturer's spelling.
15
# Names of products and trademarks appearing in this book (with or without
16
# specific notation) are likewise subject to trademark and trade protection
17
# laws and may thus fall under copyright restrictions.
25
aa_change_profile - change to another profile within an AppArmor profile
26
aa_change_onexec - change to another profile at the next exec
29
B<#include E<lt>sys/apparmor.hE<gt>>
31
B<int aa_change_profile(const char *profile);>
33
Link with B<-lapparmor> when compiling.
37
An AppArmor profile applies to an executable program; if a portion of
38
the program needs different access permissions than other portions,
39
the program can "change profile" to a different profile. To change into a
40
new profile, it can use the aa_change_profile() function to do so. It passes
41
in a pointer to the I<profile> to transition to. Transitioning to another
42
profile via aa_change_profile() is permanent and the process is not
43
permitted to transition back to the original profile. Confined programs
44
wanting to use aa_change_profile() need to have rules permitting changing
45
to the named profile. See apparmor.d(8) for details.
47
If a program wants to return out of the current profile to the
48
original profile, it should use aa_change_hat(2) instead.
50
Open file descriptors are not remediated after a call to aa_change_profile()
51
so the calling program must close(2) open file descriptors to ensure they
52
are not available after calling aa_change_profile(). As aa_change_profile()
53
is typically used just before execve(2), you may want to use open(2) or
54
fcntl(2) with close-on-exec.
56
The aa_change_onexec() function is like the aa_change_profile() function
57
except it specifies that the profile transition should take place on the
58
next exec instead of immediately. The delayed profile change takes
59
precedence over any exec transition rules within the confining profile.
60
Delaying the profile boundary has a couple of advantages, it removes the
61
need for stub transition profiles and the exec boundary is a natural security
62
layer where potentially sensitive memory is unmapped.
66
On success zero is returned. On error, -1 is returned, and
67
errno(3) is set appropriately.
75
The apparmor kernel module is not loaded or the communication via the
76
F</proc/*/attr/current> file did not conform to protocol.
80
Insufficient kernel memory was available.
84
The calling application is not confined by apparmor.
88
The application's profile has no hats defined for it.
92
The specified I<profile> does not exist in this profile or the
93
process tried to change another process's domain.
99
The following example shows a simple, if contrived, use of
100
aa_change_profile(); a typical use of aa_change_profile() will
101
aa_change_profile() just before an execve(2) so that the new
102
child process is permanently confined.
106
#include <sys/apparmor.h>
107
#include <sys/types.h>
108
#include <sys/stat.h>
113
int main(int argc, char * argv[])
117
char *execve_args[4];
119
printf("Before aa_change_profile():\n");
120
if ((fd=open("/etc/passwd", O_RDONLY)) < 0) {
121
perror("Failure opening /etc/passwd");
125
/* Confirm for ourselves that we can really read /etc/passwd */
127
if (read(fd, &buf, 10) == -1) {
128
perror("Failure reading /etc/passwd");
132
printf("/etc/passwd: %s\n", buf);
135
printf("After aa_change_profile():\n");
137
/* change profile to the "i_cant_be_trusted_anymore" profile, which
138
* should not have read access to /etc/passwd. */
139
if (aa_change_profile("i_cant_be_trusted_anymore") < 0) {
140
perror("Failure changing profile -- aborting");
144
/* confirm that we cannot read /etc/passwd */
145
execve_args[0] = "/usr/bin/head";
146
execve_args[1] = "-1";
147
execve_args[2] = "/etc/passwd";
148
execve_args[3] = NULL;
149
execve("/usr/bin/head", execve_args, NULL);
154
This code example requires a profile similar to the following to be loaded
155
with apparmor_parser(8):
157
profile i_cant_be_trusted_anymore {
168
Before aa_change_profile():
169
/etc/passwd: root:x:0:
170
After aa_change_profile():
171
/usr/bin/head: cannot open `/etc/passwd' for reading: Permission denied
174
If /tmp/change_p is to be confined as well, then the following profile can be
175
used (in addition to the one for 'i_cant_be_trusted_anymore', above):
176
# Confine change_p to be able to read /etc/passwd and aa_change_profile()
177
# to the 'i_cant_be_trusted_anymore' profile.
185
# Needed for aa_change_profile()
186
/usr/lib/libapparmor*.so* mr,
187
/proc/[0-9]*/attr/current w,
188
change_profile -> i_cant_be_trusted_anymore,
194
None known. If you find any, please report them at
195
L<http://https://bugs.launchpad.net/apparmor/+filebug>. Note that using
196
aa_change_profile(2) without execve(2) provides no memory barriers between
197
different areas of a program; if address space separation is required, then
198
separate processes should be used.
202
apparmor(7), apparmor.d(5), apparmor_parser(8), aa_change_hat(2) and
203
L<http://wiki.apparmor.net>.