avc_add_callback(3)
π avc_add_callback(3) π
okay so bestie, welcome to the SELinux API documentation corner of the manual, and today's main character is avc_add_callback β extra event notifications for your SELinux userspace object managers. yes it's a mouthful. no we're not skipping any of it. let's go β¨
πΈ NAME πΈ
avc_add_callback β additional event notification for SELinux userspace object managers
π SYNOPSIS π
#include <selinux/selinux.h>
#include <selinux/avc.h>
int avc_add_callback(int (*callback)(uint32_t event,
security_id_t ssid,
security_id_t tsid,
security_class_t tclass,
access_vector_t perms,
access_vector_t *out_retained),
uint32_t events, security_id_t ssid,
security_id_t tsid, security_class_t tclass,
access_vector_t perms);
β¨ DESCRIPTION β¨
So avc_add_callback() is literally how you register callback functions on security events. what's the point? the whole vibe is letting userspace object managers take additional action when a policy change β usually a policy reload β makes permissions get granted or revoked. it's giving "hey bestie, the rules just changed, do u wanna know?" π
eventsβ this is the bitwise-or</> of security events you wanna register the callback on. see SECURITY EVENTS below, i gotchu π«Άssid,tsid,tclass, andpermsβ these specify the source and target SID's, the target class, and the specific permissions that the callback wants to monitor. and here's the cute part: the special symbolSECSID_WILDcan be passed as the source or target and it'll cause any SID to match βcallbackβ the callback function that your userspace object manager provides. theeventargument tells you which security event happened; the remaining arguments get interpreted according to the event, as described below. the return value of the callback should bezeroon success,-1on error witherrnoset appropriately β but wait, actually peep the RETURN VALUE section below first π
π SECURITY EVENTS π
In all the cases below, ssid and/or tsid may be set to SECSID_WILD, which means the change applies to all source and/or target SID's. And unless it says otherwise, the out_retained parameter is just... unused. sitting there. unbothered. π
AVC_CALLBACK_GRANTβ permissions that were previously denied are now granted forssid,tsidwith respect totclass.permstells you which permissions to grant. slay πAVC_CALLBACK_TRY_REVOKEβ permissions that were previously granted are now conditionally revoked forssid,tsidwith respect totclass.permstells you which permissions to revoke. and here's the thing: the callback should setout_retainedto the subset ofpermswhich are retained as migrated permissions. β οΈ note thatout_retainedis ignored if the callback returns-1.AVC_CALLBACK_REVOKEβ permissions that were previously granted are now unconditionally revoked forssid,tsidwith respect totclass.permstells you which permissions to revoke. no take-backs, periodt πAVC_CALLBACK_RESETβ this one means the cache was flushed. the SID, class, and permission arguments are unused and are set toNULL. they're not even invited to the party π«AVC_CALLBACK_AUDITALLOW_ENABLEβ the permissions given bypermsshould now be audited when granted forssid,tsidwith respect totclass.AVC_CALLBACK_AUDITALLOW_DISABLEβ the permissions given bypermsshould no longer be audited when granted forssid,tsidwith respect totclass.AVC_CALLBACK_AUDITDENY_ENABLEβ the permissions given bypermsshould now be audited when denied forssid,tsidwith respect totclass.AVC_CALLBACK_AUDITDENY_DISABLEβ the permissions given bypermsshould no longer be audited when denied forssid,tsidwith respect totclass.
π RETURN VALUE π
On success, avc_add_callback() returns zero. On error, -1 is returned and errno is set appropriately. standard.
but here's the drama bestie: a return value of -1 from a callback gets interpreted as a failed policy operation. and if that happens, all the remaining callbacks registered on the event still get called. π³
Then it depends on your mode:
- In threaded mode, the netlink handler thread may then terminate and cause the userspace AVC to return
EINVALon all further permission checks untilavc_destroy(3)is called. yikes. - In non-threaded mode, the permission check on which the error occurred will return
-1and the value oferrnoencountered, back to the caller.
In both cases, a log message is produced and the kernel may be notified of the error. so like, it's not silent. it's giving receipts π§Ύ
π ERRORS π
ENOMEMβ an attempt to allocate memory failed. tragic. happens to the best of us.
β NOTES β
If the userspace AVC is running in threaded mode, callbacks registered via avc_add_callback() may be executed in the context of the netlink handler thread. this will likely introduce synchronization issues requiring the use of locks. go look at avc_init(3), i promise it helps π
Also, real talk: support for dynamic revocation and retained permissions is mostly unimplemented in the SELinux kernel module. the only security event that currently gets exercised is AVC_CALLBACK_RESET. so like, one of the eight is actually out here living its life π
π AUTHOR π
Eamon Walsh <ewalsh@tycho.nsa.gov>
π¦ SEE ALSO π¦
avc_init(3), avc_has_perm(3), avc_context_to_sid(3), avc_cache_stats(3), security_compute_av(3) selinux(8)
okay that's the whole page, no cap, every flag and event and error accounted for π«Ά this was the SELinux API documentation page for avc_add_callback(3), dated 9 June 2004 β yes she's an elder but she still ate, and honestly? iconic behavior. mwah πβ¨π
π¦ where this page comes from
- alpine 3.24: libselinux-doc 3.10-r1 Β· Public-Domain
- centos-stream 10: libselinux-devel 3.11-3.el10 Β· LicenseRef-Fedora-Public-Domain
- centos-stream 9: libselinux-devel 3.6-5.el9 Β· Public Domain
- centos-stream 9: libselinux-devel 3.6-5.el9 Β· Public Domain
- debian bookworm: libselinux1-dev 3.4-1+b6
- debian trixie: libselinux1-dev 3.8.1-1 Β· LicenseRef-public-domain
- fedora 43: libselinux-devel 3.9-5.fc43 Β· LicenseRef-Fedora-Public-Domain
- fedora 43: libselinux-devel 3.9-5.fc43 Β· LicenseRef-Fedora-Public-Domain
- fedora 44: libselinux-devel 3.10-1.fc44 Β· LicenseRef-Fedora-Public-Domain
- fedora 44: libselinux-devel 3.10-1.fc44 Β· LicenseRef-Fedora-Public-Domain
- fedora 44: libselinux-devel 3.11-2.fc44 Β· LicenseRef-Fedora-Public-Domain
- fedora 44: libselinux-devel 3.11-2.fc44 Β· LicenseRef-Fedora-Public-Domain
- nixos 26.05: libselinux 3.10
- nixpkgs unstable: libselinux 3.11
- opensuse-leap 16.0: libselinux-devel 3.8.1-160000.4.1 Β· SUSE-Public-Domain
- opensuse-leap 16.0: libselinux-devel 3.8.1-160000.4.1 Β· SUSE-Public-Domain
- opensuse-leap 16.0: libselinux-devel 3.8.1-160000.4.1 Β· SUSE-Public-Domain
- opensuse-leap 16.0: libselinux-devel 3.8.1-160000.4.1 Β· SUSE-Public-Domain
- ubuntu jammy: libselinux1-dev 3.3-1build2
- ubuntu noble: libselinux1-dev 3.5-2ubuntu2 Β· LicenseRef-public-domain
- ubuntu noble: libselinux1-dev 3.5-2ubuntu2.1 Β· LicenseRef-public-domain
- ubuntu questing: libselinux1-dev 3.8.1-1build1
- ubuntu resolute: libselinux-dev 3.9-4build1 Β· LicenseRef-public-domain
- ubuntu stonking: libselinux-dev 3.11-2.1 Β· LicenseRef-public-domain
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms