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, and perms β€” 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 symbol SECSID_WILD can 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. the event argument 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 be zero on success, -1 on error with errno set 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 for ssid, tsid with respect to tclass. perms tells you which permissions to grant. slay πŸ’–
  • AVC_CALLBACK_TRY_REVOKE β€” permissions that were previously granted are now conditionally revoked for ssid, tsid with respect to tclass. perms tells you which permissions to revoke. and here's the thing: the callback should set out_retained to the subset of perms which are retained as migrated permissions. ⚠️ note that out_retained is ignored if the callback returns -1.
  • AVC_CALLBACK_REVOKE β€” permissions that were previously granted are now unconditionally revoked for ssid, tsid with respect to tclass. perms tells 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 to NULL. they're not even invited to the party 🚫
  • AVC_CALLBACK_AUDITALLOW_ENABLE β€” the permissions given by perms should now be audited when granted for ssid, tsid with respect to tclass.
  • AVC_CALLBACK_AUDITALLOW_DISABLE β€” the permissions given by perms should no longer be audited when granted for ssid, tsid with respect to tclass.
  • AVC_CALLBACK_AUDITDENY_ENABLE β€” the permissions given by perms should now be audited when denied for ssid, tsid with respect to tclass.
  • AVC_CALLBACK_AUDITDENY_DISABLE β€” the permissions given by perms should no longer be audited when denied for ssid, tsid with respect to tclass.

πŸ’… 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 EINVAL on all further permission checks until avc_destroy(3) is called. yikes.
  • In non-threaded mode, the permission check on which the error occurred will return -1 and the value of errno encountered, 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