These docs are under active development and cover the v0.20 Kobicha security model.
On this page
§11.6

The Set-Security Interface

All SD modification flows through a single KACS syscall. The caller provides a file descriptor or path, a bitmask specifying which SD components to modify, and a self-relative SD blob containing the new values.

§11.6.1 Security information flags

Flag Component Required right
OWNER_SECURITY_INFORMATION Owner SID WRITE_OWNER
GROUP_SECURITY_INFORMATION Group SID WRITE_OWNER
DACL_SECURITY_INFORMATION Discretionary ACL WRITE_DAC
SACL_SECURITY_INFORMATION System ACL ACCESS_SYSTEM_SECURITY
LABEL_SECURITY_INFORMATION Mandatory integrity label WRITE_OWNER + integrity constraints

The kernel validates the SD blob structurally (parseable, well-formed ACEs, valid SIDs, size within 64 KB) then merges only the indicated components into the existing SD. Unindicated components are preserved unchanged. After merging, the resulting SD MUST have a non-null owner and non-null group. If the merge would produce an SD without an owner or group (e.g., setting OWNER_SECURITY_INFORMATION with a null owner on an object that has no existing owner), the operation fails.

MIC and PIP apply to these checks. A low-integrity caller MUST NOT modify a high-integrity file's SD even if the DACL grants WRITE_OWNER.

§11.6.2 Ownership constraints

Ownership changes are a two-phase check. Phase 1 (AccessCheck or granted mask): the caller MUST have WRITE_OWNER — the right to change the owner. Phase 2 (set-security validation): the specific SID being set as owner MUST be permitted. Having WRITE_OWNER does not grant the ability to set an arbitrary owner SID.

When setting a new owner, the caller MAY only set the owner to:

  • Their own SID.
  • A group SID on the token with SE_GROUP_OWNER.

SeTakeOwnershipPrivilege allows setting ownership to the caller's own SID regardless of the current SD. SeRestorePrivilege allows setting ownership to any arbitrary SID.

§11.6.3 Integrity label constraints

Without SeRelabelPrivilege, callers MAY only set a label at or below their own integrity level. With SeRelabelPrivilege, any level is permitted.

§11.6.4 SeRestorePrivilege bypass

SeRestorePrivilege bypasses the access check when kacs_set_sd runs a live AccessCheck — i.e., when called via O_PATH fd + AT_EMPTY_PATH, via pidfd, or via path. The privilege fires in the AccessCheck pipeline and grants all requested rights including WRITE_OWNER, WRITE_DAC, and ACCESS_SYSTEM_SECURITY.

When kacs_set_sd is called on a normal (non-O_PATH) file fd, the required rights are checked against the fd's cached granted mask — no AccessCheck runs, so SeRestorePrivilege has no effect. A caller who needs the privilege bypass MUST use the O_PATH + AT_EMPTY_PATH path. This is the mechanism for backup restoration, administrative SD repair, and the missing-SD repair path.

§11.6.5 Mandatory resource attribute protection

When a caller modifies the SACL (SACL_SECURITY_INFORMATION), the kernel compares the existing and new SACLs for changes to SYSTEM_RESOURCE_ATTRIBUTE_ACE entries. If an existing resource attribute has the CLAIM_SECURITY_ATTRIBUTE_MANDATORY flag (0x0020), the caller MUST NOT remove it or modify its values unless the caller has SeTcbPrivilege. If the caller lacks SeTcbPrivilege and attempts to remove or modify a MANDATORY attribute, the entire kacs_set_sd call fails.

This prevents file owners (who may have ACCESS_SYSTEM_SECURITY or WRITE_DAC) from stripping classification tags that conditional ACEs rely on. Only TCB processes (typically automated classifiers or administrative tools running under peinit) can modify mandatory attributes.

§11.6.6 Write mechanics

After merging:

  1. Serialize the updated SD to self-relative binary format.
  2. Write the appropriate xattr via an internal kernel path that bypasses the setxattr denial hook.
  3. Update the in-memory SD cache in the same operation.
  4. Emit an audit event if the file's SACL contains a matching audit ACE.

Concurrent set-security calls on the same inode are serialized by the inode mutex. RCU readers on the AccessCheck path are not blocked.