aa_kernel_interface(3)

πŸ’… aa_kernel_interface β€” bestie edition

okay so this is a page from the AppArmor manual, section 3 (that's the library-functions girlies πŸŽ€). It's all about aa_kernel_interface, which is an opaque object representing the AppArmor kernel interface for policy loading, replacing, and removing. Like, the little go-between that talks to your kernel about policy. Iconic behaviour, honestly.


✨ NAME ✨

So the whole cast of characters on this page is:

  • aa_kernel_interface β€” the opaque object itself: an opaque object representing the AppArmor kernel interface for policy loading, replacing, and removing. She's mysterious. She's opaque. She runs the show. πŸ’…
  • aa_kernel_interface_new β€” create a new aa_kernel_interface object from an optional path. New object, who dis ✨
  • aa_kernel_interface_ref β€” increments the ref count of an aa_kernel_interface object. Keeping her alive, no cap 🫢
  • aa_kernel_interface_unref β€” decrements the ref count and frees the aa_kernel_interface object when 0. Bye bestie 😭
  • aa_kernel_interface_load_policy β€” load a policy from a buffer into the kernel. Buffer to kernel, direct flight πŸ›«
  • aa_kernel_interface_load_policy_from_file β€” load a policy from a file into the kernel. File girlies rise 🌸
  • aa_kernel_interface_load_policy_from_fd β€” load a policy from a file descriptor into the kernel. fd girlies, your moment πŸ”₯
  • aa_kernel_interface_replace_policy β€” replace a policy in the kernel with a policy from a buffer. Out with the old πŸ’€
  • aa_kernel_interface_replace_policy_from_file β€” replace a policy in the kernel with a policy from a file. Glow-up via filesystem πŸ’–
  • aa_kernel_interface_replace_policy_from_fd β€” replace a policy in the kernel with a policy from a file descriptor. Glow-up via fd, iykyk πŸ¦‹
  • aa_kernel_interface_remove_policy β€” remove a policy from the kernel. Blocked. Unloaded. Gone πŸ™ˆ
  • aa_kernel_interface_write_policy β€” write a policy to a file descriptor. Sending it out into the world ✨

πŸ¦‹ SYNOPSIS πŸ¦‹

First things first, you gotta include the header and link the library. Copy these exactly, bestie:

#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);

And when you compile, link with -lapparmor. Don't forget or she literally will not link. πŸ’€


πŸ’– DESCRIPTION πŸ’–

the object herself

The aa_kernel_interface object contains information about the AppArmor kernel interface for policy loading, replacing, and removing. She's opaque, meaning you don't peek inside, you just use her. Main character energy, but make it a struct. πŸ‘‘

making one: aa_kernel_interface_new()

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

Deets, because details matter:

  • 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. Like, compatibility check first, always 🫢
  • If apparmorfs is NULL, then the default location is used.
  • The allocated kernel_interface object must be freed using aa_kernel_interface_unref(). That's not optional, bestie, that's a leak waiting to happen 😭

refcounting: aa_kernel_interface_ref() and aa_kernel_interface_unref()

aa_kernel_interface_ref() increments the reference count on the kernel_interface object. Keeping her alive ✨

aa_kernel_interface_unref() decrements the reference count on the kernel_interface object and releases all corresponding resources when the reference count reaches zero. And that's the free. Rest in peace, queen πŸ’

loading vs replacing (the plot twist)

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. Rude of it, but okay.

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.

And plot twist: the aa_kernel_interface_replace() functions can also be used to load a policy that does not correspond to a previously loaded policy. So replace is lowkey the flexible one. Slay πŸ’…

buffers, files, and fds β€” the three flavours

  • When loading or replacing from a buffer, the buffer will contain binary data. The size argument must specify the size of the buffer argument. Don't guess the size. Actually measure. Fr fr.
  • 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. Go read it, it's giving essential context πŸ“–
  • 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. Open for reading = mandatory. Offset set properly = also mandatory. No skipping steps 😀

unloading: aa_kernel_interface_remove_policy()

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. Not a nickname. Not a vibe. The fully qualified name.

The operation will fail if a policy matching fqname is not found. Nothing to remove? She'll tell you. πŸ’€

writing out: aa_kernel_interface_write_policy()

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. Same energy as before: open right, offset right, no chaos. ✨


🌈 RETURN VALUE 🌈

  • aa_kernel_interface_new() returns 0 on success, and *kernel_interface will point to an aa_kernel_interface object that must be freed by aa_kernel_interface_unref(). πŸŽ€
  • On error, -1 is returned, with errno set appropriately, and *kernel_interface will be set to NULL. Clean failure, we love an honest error.
  • aa_kernel_interface_ref() returns the value of kernel_interface. She just hands her back to you 🫢
  • 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. So like, the exact error comes from whatever went wrong underneath β€” no invented drama, just the real code. 🧚


⭐ NOTES ⭐

  • All aa_kernel_interface functions described above are present in libapparmor version 2.10 and newer. Older than that? Sorry babe.
  • aa_kernel_interface_unref() saves the value of errno when called and restores errno before exiting in libapparmor version 2.12 and newer. Your errno survives the cleanup. Respect. πŸ™Œ

πŸ’€ BUGS πŸ’€

None known. If you find any, please report them at <https://gitlab.com/apparmor/apparmor/-/issues>. Do your civic duty, bestie 🫑


πŸŽ€ SEE ALSO πŸŽ€

aa_features(3), openat(2) and <https://wiki.apparmor.net>. Go read, go learn, go slay πŸ“šβœ¨


okay that's the whole page, you're officially an aa_kernel_interface girlie now πŸ’…

this has been the AppArmor manual, AppArmor 4.1.8, dated 2026-10-18 β€” aa_kernel_interface(3), signing off πŸ¦‹πŸ’–

πŸ“¦ where this page comes from
  • arch rolling: apparmor 4.1.8-2 Β· GPL-2.0-only AND LGPL-2.0-only AND LGPL-2.1-only
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms