aa_change_hat − change to or from a "hat" within a AppArmor profile


#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.


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".


On success zero is returned. On error, −1 is returned, and errno(3) is set appropriately.



The apparmor kernel module is not loaded or the communication via the /proc/*/attr/current file did not conform to protocol.


Insufficient kernel memory was available.


The calling application is not confined by apparmor.


The application’s profile has no hats defined for it.


The specified subprofile does not exist in this profile or the process tried to change another process’s domain.


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. */
        /* 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");
        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");
        /* confirm that we cannot read /etc/passwd */
        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


None known. If you find any, please report them at <http://https://bugs.launchpad.net/apparmor/+filebug>. 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.


apparmor(7), apparmor.d(5), apparmor_parser(8), aa_change_profile(2), aa_getcon(2) and <http://wiki.apparmor.net>.


Personal Opportunity - Free software gives you access to billions of dollars of software at no cost. Use this software for your business, personal use or to develop a profitable skill. Access to source code provides access to a level of capabilities/information that companies protect though copyrights. Open source is a core component of the Internet and it is available to you. Leverage the billions of dollars in resources and capabilities to build a career, establish a business or change the world. The potential is endless for those who understand the opportunity.

Business Opportunity - Goldman Sachs, IBM and countless large corporations are leveraging open source to reduce costs, develop products and increase their bottom lines. Learn what these companies know about open source and how open source can give you the advantage.

Free Software

Free Software provides computer programs and capabilities at no cost but more importantly, it provides the freedom to run, edit, contribute to, and share the software. The importance of free software is a matter of access, not price. Software at no cost is a benefit but ownership rights to the software and source code is far more significant.

Free Office Software - The Libre Office suite provides top desktop productivity tools for free. This includes, a word processor, spreadsheet, presentation engine, drawing and flowcharting, database and math applications. Libre Office is available for Linux or Windows.

Free Books

The Free Books Library is a collection of thousands of the most popular public domain books in an online readable format. The collection includes great classical literature and more recent works where the U.S. copyright has expired. These books are yours to read and use without restrictions.

Source Code - Want to change a program or know how it works? Open Source provides the source code for its programs so that anyone can use, modify or learn how to write those programs themselves. Visit the GNU source code repositories to download the source.


Study at Harvard, Stanford or MIT - Open edX provides free online courses from Harvard, MIT, Columbia, UC Berkeley and other top Universities. Hundreds of courses for almost all major subjects and course levels. Open edx also offers some paid courses and selected certifications.

Linux Manual Pages - A man or manual page is a form of software documentation found on Linux/Unix operating systems. Topics covered include computer programs (including library and system calls), formal standards and conventions, and even abstract concepts.