avc_has_perm(3)
π avc_has_perm β SELinux API documentation π
okay so bestie, welcome to the avc_has_perm(3) page β¨ this is the SELinux access-decision corner of the manual, and we're gonna get you a decision, an audit trail, and a little cache moment. let's go π«Ά
πΈ NAME πΈ
avc_has_perm, avc_has_perm_noaudit, avc_audit, avc_entry_ref_init β obtain and audit SELinux access decisions π
β¨ SYNOPSIS β¨
#include <selinux/selinux.h>
#include <selinux/avc.h>
void avc_entry_ref_init(struct avc_entry_ref *aeref);
int avc_has_perm(security_id_t ssid, security_id_t tsid,
security_class_t tclass, access_vector_t requested,
struct avc_entry_ref *aeref, void *auditdata);
int avc_has_perm_noaudit(security_id_t ssid, security_id_t tsid,
security_class_t tclass, access_vector_t requested,
struct avc_entry_ref *aeref, struct av_decision *avd);
void avc_audit(security_id_t ssid, security_id_t tsid,
security_class_t tclass, access_vector_t requested,
struct av_decision *avd, int result, void *auditdata);
π¦ DESCRIPTION π¦
ngl, the vibe check on these functions is: direct use is generally discouraged π instead, the higher level interface selinux_check_access(3) is the moment, because it automatically handles the dynamic mapping of class and permission names to their policy values and proper handling of allow_unknown. so like, she does the work for you, queen behavior π
when you are using any of these functions that take policy integer values for classes or permissions as inputs, use string_to_security_class(3) and string_to_av_perm(3) to map the class and permission names to their policy values. and listen β these values may change across a policy reload π so they should be re-acquired on every use, or by using a SELINUX_CB_POLICYLOAD callback set via selinux_set_callback(3). don't be caught lacking with stale constants fr fr.
an alternative approach is to use selinux_set_mapping(3) to create a mapping from class and permission index values used by the application to the policy values, which lets the application pass its own fixed constants for the classes and permissions to these functions and have them internally mapped on demand β¨ however, this also requires setting up a callback as above to address policy reloads. same energy, same homework π
avc_entry_ref_init()β initializes anavc_entry_refstructure; peep ENTRY REFERENCES below. this function may be implemented as a macro, iykyk.avc_has_perm()β checks whether the requested permissions are granted for subject SID ssid and target SID tsid, interpreting the permissions based on tclass, and updating aeref, if non-NULL, to refer to a cache entry with the resulting decision. the granting or denial of permissions is audited in accordance with the policy. the auditdata parameter is for supplemental auditing; seeavc_audit()below πavc_has_perm_noaudit()β behaves asavc_has_perm()without producing an audit message π€« the access decision is returned in avd and can be passed toavc_audit()explicitly.avc_audit()β produces an audit message for the access query represented by ssid, tsid, tclass, and requested, with a decision represented by avd. pass the value returned byavc_has_perm_noaudit()as result. the auditdata parameter is passed to the user-suppliedfunc_auditcallback and can be used to add supplemental information to the audit message; seeavc_init(3)π
π ENTRY REFERENCES π
entry references can be used to speed cache performance for repeated queries on the same subject and target π₯ the userspace AVC will check the aeref argument, if supplied, before searching the cache on a permission query. after a query is performed, aeref will be updated to reference the cache entry for that query. a subsequent query on the same subject and target will then have the decision at hand without having to walk the cache. it's giving shortcut, it's giving efficiency, we love her π
after declaring an avc_entry_ref structure, use avc_entry_ref_init() to initialize it before passing it to avc_has_perm() or avc_has_perm_noaudit() for the first time.
π¨ bestie. using an uninitialized structure will produce undefined behavior. not a cute look. initialize it. periodt.
π« RETURN VALUE π«
if requested permissions are granted, zero is returned π if requested permissions are denied or an error occurred, -1 is returned and errno is set appropriately π
in permissive mode, zero will be returned and errno unchanged even if permissions were denied π avc_has_perm() will still produce an audit message in this case.
π ERRORS π
EACCESβ a requested permission was denied. rude but fair πEINVALβ the tclass and/or the security contexts referenced by ssid and tsid are not recognized by the currently loaded policy.ENOMEMβ an attempt to allocate memory failed.
π§ NOTES π§
internal errors encountered by the userspace AVC may cause certain values of errno to be returned unexpectedly π³ for example, netlink socket errors may produce EACCES or EINVAL. make sure that userspace object managers are granted appropriate access to netlink by the policy. like, set them up properly, bestie, don't leave them hanging π«Ά
π AUTHOR π
originally Eamon Walsh. updated by Stephen Smalley <stephen.smalley.work@gmail.com> β¨
π SEE ALSO π
selinux_check_access(3), string_to_security_class(3), string_to_av_perm(3), selinux_set_callback(3), selinux_set_mapping(3), avc_init(3), avc_context_to_sid(3), avc_cache_stats(3), avc_add_callback(3), security_compute_av(3), selinux(8)
and that's the page, bestie!! this one's dated 27 May 2004, and it comes to you from the SELinux API documentation collection π go forth and get those access decisions, you absolute icon π β¨πΈ
π¦ 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 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 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