Appendix 3.E LSM integration

KACS registers as the pkm Linux Security Module. This appendix is an implementation inventory for kernel developers: it describes the storage and call sites behind the contracts in this chapter. These C structures and callbacks are kernel-private, not userspace layouts or extension APIs. The exported ABI remains in §3.A.

The inventory comes from pkm/kacs/lsm.c (pkm_blob_sizes and pkm_hooks[]), the structures in kacs/lsm_internal.h, and the callback implementations listed below. When changing those declarations, update this inventory with the same change. The hook matrix preserves registration order; each row names an actual LSM_HOOK_INIT entry.

3.E.1 Security-blob inventory #

pkm_blob_sizes requests eight sized blob families. Each lbs_* entry is initialized with sizeof the corresponding structure; Linux's LSM infrastructure assigns its offset in the object's security storage. Byte sizes and offsets depend on the build and are not fixed by this manual.

LSM size entryKACS structureState carried
lbs_credpkm_kacs_cred_securityToken reference, shared process_state, projected UID/GID, and the pending descriptor used while overlayfs creates or copies up an inode.
lbs_taskpkm_kacs_task_securityShared process_state, usermode-helper and impersonation state, the applied primary-installation epoch and thread-enrollment callback, deferred privilege-audit work, native-open/create requests, write/metadata decisions, and narrowly scoped StrataFS creation, supersede, cleanup and delete-on-close context.
lbs_sockpkm_kacs_socket_securitySocket descriptor, conveyed peer/listener identities, token-conveyance cache and impersonation limits, binder identity/reuse decision, and the committed socket-owner identity used by network policy.
lbs_ipcpkm_kacs_ipc_securityRefcounted descriptor and lock for a System V message queue, shared-memory segment or semaphore array.
lbs_filepkm_kacs_file_securityCached granted_access and continuous_audit_mask, copy-up context and phase generation, managed, delete_on_close, and the referenced token that armed deferred deletion.
lbs_backing_filepkm_kacs_backing_file_securityCached granted_access and continuous_audit_mask, plus managed and inherited, for the explicit outer-to-backing-file snapshot transfer.
lbs_inodepkm_kacs_inode_securityLock and RCU descriptor-cache pointer, delete-on-close lineage and signed-exec pin counters, and the deferred descriptor-persistence state. Test-only members exist under CONFIG_SECURITY_PKM_KUNIT.
lbs_superblockpkm_kacs_superblock_securityMount-policy lock, template descriptor bytes/length, policy generation and mount policy.

The additional lbs_xattr_count = 1 reserves one xattr-initialization slot. It is not a ninth object blob or a byte-size declaration.

The file blob uses separate u8 managed and u8 delete_on_close fields. There is no flags member or KACS_FILE_FACS_MANAGED constant. The backing-file blob is distinct from the ordinary file blob: its inherited marker records explicit adoption of the outer description's cached grants and continuous-audit mask (§3.9.7).

The task blob reaches process-wide state through its process_state pointer. The refcounted pkm_kacs_process_state contains process_guid, pip_type, pip_trust, one u32 mitigation_bits, the KMES rate bucket, the process_sd reference and process-scoped privilege-audit bookkeeping. It also holds primary_lock, desired_primary_token and primary_epoch, which order primary-token installation across the process's threads (§3.2.3). PIP identity and the process descriptor are not inline task-blob fields; the process mitigations are not nine independent booleans. This shared state is separate from the effective token used during impersonation.

The credential blob's pending_create_sd has the lifetime of an override credential. Overlayfs uses it to stamp the descriptor computed for the original object or caller/parent onto the actual created inode; credential preparation does not inherit it into a derived credential. The task blob's internal SD read/write depth and operation contexts similarly identify specific kernel work; they are not caller-settable authorization flags.

3.E.2 Registered hook matrix #

The current pkm_hooks[] table contains 99 registrations. Paths in the last column are relative to the pkm source repository. A callback's presence here identifies where KACS is called; the operation's access, privilege and lifetime rules remain specified in the relevant chapter.

Linux LSM hookKACS callbackImplementation
cred_preparepkm_kacs_cred_preparekacs/cred_lifecycle.c
cred_transferpkm_kacs_cred_transferkacs/cred_lifecycle.c
cred_alloc_blankpkm_kacs_cred_alloc_blankkacs/cred_lifecycle.c
cred_freepkm_kacs_cred_freekacs/cred_lifecycle.c
sb_alloc_securitypkm_kacs_sb_alloc_securitykacs/object_lifecycle.c
sb_free_securitypkm_kacs_sb_free_securitykacs/object_lifecycle.c
sb_kern_mountpkm_kacs_sb_kern_mountkacs/mnt_namespace.c
inode_alloc_securitypkm_kacs_inode_alloc_securitykacs/object_lifecycle.c
inode_free_security_rcupkm_kacs_inode_free_security_rcukacs/object_lifecycle.c
inode_getattrpkm_kacs_inode_getattrkacs/file_metadata.c
path_notifypkm_kacs_path_notifykacs/namespace.c
inode_setattrpkm_kacs_inode_setattrkacs/file_metadata.c
inode_file_getattrpkm_kacs_inode_file_getattrkacs/file_metadata.c
inode_file_setattrpkm_kacs_inode_file_setattrkacs/file_metadata.c
inode_xattr_skipcappkm_kacs_inode_xattr_skipcapkacs/file_metadata.c
inode_getxattrpkm_kacs_inode_getxattrkacs/file_metadata.c
inode_setxattrpkm_kacs_inode_setxattrkacs/file_metadata.c
inode_post_setxattrpkm_kacs_inode_post_setxattrkacs/file_metadata.c
inode_removexattrpkm_kacs_inode_removexattrkacs/file_metadata.c
inode_listxattrpkm_kacs_inode_listxattrkacs/file_metadata.c
inode_copy_uppkm_kacs_inode_copy_upkacs/file_metadata.c
inode_copy_up_xattrpkm_kacs_inode_copy_up_xattrkacs/file_metadata.c
inode_follow_linkpkm_kacs_inode_follow_linkkacs/file_metadata.c
inode_set_aclpkm_kacs_inode_set_aclkacs/file_metadata.c
inode_remove_aclpkm_kacs_inode_remove_aclkacs/file_metadata.c
inode_getsecuritypkm_kacs_inode_getsecuritykacs/file_metadata.c
inode_permissionpkm_kacs_inode_permissionkacs/namespace.c
inode_createpkm_kacs_inode_createkacs/namespace.c
inode_linkpkm_kacs_inode_linkkacs/namespace.c
inode_unlinkpkm_kacs_inode_unlinkkacs/namespace.c
inode_symlinkpkm_kacs_inode_symlinkkacs/namespace.c
inode_mkdirpkm_kacs_inode_mkdirkacs/namespace.c
inode_rmdirpkm_kacs_inode_rmdirkacs/namespace.c
inode_mknodpkm_kacs_inode_mknodkacs/namespace.c
inode_renamepkm_kacs_inode_renamekacs/namespace.c
inode_readlinkpkm_kacs_inode_readlinkkacs/namespace.c
inode_init_securitypkm_kacs_inode_init_securitykacs/namespace.c
inode_post_create_tmpfilepkm_kacs_copy_up_post_create_tmpfilekacs/copy_up.c
dentry_create_files_aspkm_kacs_dentry_create_files_askacs/namespace.c
file_alloc_securitypkm_kacs_file_alloc_securitykacs/object_lifecycle.c
backing_file_allocpkm_kacs_backing_file_allockacs/object_lifecycle.c
file_releasepkm_kacs_file_releasekacs/object_lifecycle.c
file_openpkm_kacs_file_openkacs/file_access.c
file_receivepkm_kacs_file_receivekacs/object_lifecycle.c
file_permissionpkm_kacs_file_permissionkacs/file_access.c
file_ioctlpkm_kacs_file_ioctlkacs/file_access.c
file_ioctl_compatpkm_kacs_file_ioctl_compatkacs/file_access.c
file_lockpkm_kacs_file_lockkacs/file_access.c
file_fcntlpkm_kacs_file_fcntlkacs/file_access.c
file_truncatepkm_kacs_file_truncatekacs/file_access.c
kernel_read_filepkm_kacs_kernel_read_filekacs/firmware.c
kernel_post_read_filepkm_kacs_kernel_post_read_filekacs/firmware.c
task_allocpkm_kacs_task_allockacs/task_lifecycle.c
task_freepkm_kacs_task_freekacs/task_lifecycle.c
sk_alloc_securitypkm_kacs_sk_alloc_securitykacs/socket.c
sk_free_securitypkm_kacs_sk_free_securitykacs/socket.c
sk_clone_securitypkm_kacs_sk_clone_securitykacs/socket.c
socket_post_createpkm_kacs_socket_post_createkacs/socket.c
socket_bindpkm_kacs_socket_bindkacs/socket.c
socket_connectpkm_kacs_socket_connectkacs/socket.c
unix_stream_connectpkm_kacs_unix_stream_connectkacs/socket.c
unix_may_sendpkm_kacs_unix_may_sendkacs/socket.c
socket_listenpkm_kacs_socket_listenkacs/socket.c
ipc_permissionpkm_kacs_ipc_permissionkacs/ipc.c
msg_queue_alloc_securitypkm_kacs_ipc_alloc_securitykacs/ipc.c
msg_queue_free_securitypkm_kacs_ipc_free_securitykacs/ipc.c
msg_queue_msgctlpkm_kacs_msg_queue_msgctlkacs/ipc.c
shm_alloc_securitypkm_kacs_ipc_alloc_securitykacs/ipc.c
shm_free_securitypkm_kacs_ipc_free_securitykacs/ipc.c
shm_shmctlpkm_kacs_shm_shmctlkacs/ipc.c
sem_alloc_securitypkm_kacs_ipc_alloc_securitykacs/ipc.c
sem_free_securitypkm_kacs_ipc_free_securitykacs/ipc.c
sem_semctlpkm_kacs_sem_semctlkacs/ipc.c
task_killpkm_kacs_task_killkacs/process_access.c
ptrace_access_checkpkm_kacs_ptrace_access_checkkacs/process_access.c
ptrace_tracemepkm_kacs_ptrace_tracemekacs/process_access.c
task_setnicepkm_kacs_task_setnicekacs/process_access.c
task_setschedulerpkm_kacs_task_setschedulerkacs/process_access.c
task_setiopriopkm_kacs_task_setiopriokacs/process_access.c
task_setpgidpkm_kacs_task_setpgidkacs/process_access.c
task_getpgidpkm_kacs_task_getpgidkacs/process_access.c
task_getsidpkm_kacs_task_getsidkacs/process_access.c
task_getschedulerpkm_kacs_task_getschedulerkacs/process_access.c
task_getiopriopkm_kacs_task_getiopriokacs/process_access.c
task_movememorypkm_kacs_task_movememorykacs/process_access.c
task_fix_setuidpkm_kacs_task_fix_setuidkacs/cred_projection.c
task_fix_setgidpkm_kacs_task_fix_setgidkacs/cred_projection.c
task_fix_setgroupspkm_kacs_task_fix_setgroupskacs/cred_projection.c
task_prlimitpkm_kacs_task_prlimitkacs/process_access.c
capablepkm_kacs_capablekacs/capability.c
capsetpkm_kacs_capsetkacs/capability.c
task_prctlpkm_kacs_task_prctlkacs/psb.c
mmap_filepkm_kacs_mmap_filekacs/psb.c
mmap_backing_filepkm_kacs_mmap_backing_filekacs/object_lifecycle.c
file_mprotectpkm_kacs_file_mprotectkacs/psb.c
bprm_check_securitypkm_kacs_bprm_check_securitykacs/exec.c
bprm_creds_from_filepkm_kacs_bprm_creds_from_filekacs/exec.c
bprm_committing_credspkm_kacs_bprm_committing_credskacs/exec.c
bprm_committed_credspkm_kacs_bprm_committed_credskacs/exec.c

3.E.3 Direct file-metadata entry points #

An LSM hook receives the arguments supplied by the Linux hook API. Some file-descriptor operations also need the particular open file's cached FACS grant. PKM's patch series therefore calls KACS directly at the file-descriptor call site, before the later inode-level work. These functions are declared and called directly under CONFIG_SECURITY_PKM; they are not additional entries in pkm_hooks[] and are not dispatched through another LSM's hook table.

File-descriptor operationDirect KACS entry pointPatch in kernel/patches/fs/
Change modepkm_kacs_file_chmodopen-fchmod-fchown-gate.patch
Change owner/grouppkm_kacs_file_chownopen-fchmod-fchown-gate.patch
Change timestamps through a file descriptorpkm_kacs_file_utimensutimes-gate.patch
Read file attributes through a file descriptorpkm_kacs_file_getattrstat-getattr-gate.patch
Read an xattr through a file descriptorpkm_kacs_file_sd_xattr_getxattr-raw-sd-guard.patch
Set an xattr through a file descriptorpkm_kacs_file_sd_xattr_setxattr-raw-sd-guard.patch
Remove an xattr through a file descriptorpkm_kacs_file_sd_xattr_removexattr-raw-sd-guard.patch

All seven implementations are in kacs/file_metadata.c. The xattr functions enforce the file's metadata grant as well as the separate rules for protected SD attributes; their names do not make raw SD-xattr access a supported security-descriptor API.

The names security_file_setattr, security_file_getattr, security_file_getxattr and security_file_setxattr do not name hooks provided by this kernel. In particular, do not confuse them with the real inode_file_getattr and inode_file_setattr registrations in the matrix: those receive a dentry and struct file_kattr, not the open file whose cached grant the direct entry points consult. The metadata decision record connects the file-level check to the later inode-level operation. This table covers those file-metadata entry points, not every direct KACS call in PKM's patch series.

3.E.4 Reserved access-mask bits #

RESERVED_ACCESS_MASK_BITS in crates/kacs-core/src/access_mask.rs is 0x0ce0_0000 (bits 21, 22, 23, 26 and 27, counting from zero). It remains a private evaluator constant, not a new UAPI definition. §3.8.10 already specifies the public behavior: reserved bits in a desired mask or any ACE mask reject the check, rather than being ignored. This inventory records the implementation value without adding another exported spelling.

Edit this page