3.9.6 The Set-Security Interface

All descriptor modification flows through one syscall. The caller provides a file descriptor or path, a bitmask naming which components to modify, and a self-relative descriptor blob carrying the new values.

FlagComponentRequired right
OWNER_SECURITY_INFORMATIONOwner SIDWRITE_OWNER
GROUP_SECURITY_INFORMATIONGroup SIDWRITE_OWNER
DACL_SECURITY_INFORMATIONDiscretionary ACLWRITE_DAC
SACL_SECURITY_INFORMATIONSystem ACLACCESS_SYSTEM_SECURITY
LABEL_SECURITY_INFORMATIONMandatory integrity labelWRITE_OWNER, plus the integrity constraints below

The blob is validated structurally — parseable, well-formed ACEs, valid SIDs, at most 65535 bytes — and then only the indicated components are merged into the existing descriptor. Unindicated components are preserved unchanged.

The input is always one self-relative descriptor subset, never a raw SID or ACL fragment. SACL_SECURITY_INFORMATION and LABEL_SECURITY_INFORMATION cannot be combined in one call, because both target the SACL field with incompatible meanings; the pair fails with EINVAL.

A SACL_SECURITY_INFORMATION write replaces the object's entire SACL. A LABEL_SECURITY_INFORMATION write interprets the input SACL as the label subset only: no SACL component removes the explicit mandatory label and returns the object to the default unlabelled state; a present SACL contains exactly one non-inherit-only SYSTEM_MANDATORY_LABEL_ACE and nothing else; and the object's non-label SACL ACEs are preserved.

After merging, the result still has a non-null owner — the group SID may be null — and a merge that would leave no owner fails.

MIC and PIP apply to these checks. A low-integrity caller cannot modify a high-integrity file's descriptor even where the DACL grants WRITE_OWNER.

3.9.6.1 Ownership #

A new owner may be set only to the caller's own SID, or to a group SID on the token carrying SE_GROUP_OWNER. SeTakeOwnershipPrivilege allows setting ownership to the caller's own SID regardless of what the current descriptor says, and SeRestorePrivilege allows any arbitrary SID.

3.9.6.2 Integrity labels #

Without SeRelabelPrivilege a caller may set a label only at or below its own integrity level; with it, any level.

The constraint applies through both paths — the dedicated label subset, and a label ACE embedded in a full SACL write. A SACL write whose ACL contains a mandatory label ACE raising integrity above the caller's level requires SeRelabelPrivilege exactly as the label path does, even though the SACL component itself is gated only by ACCESS_SYSTEM_SECURITY.

3.9.6.3 The SeRestorePrivilege bypass #

SeRestorePrivilege fires inside the AccessCheck pipeline, so it bypasses the check only where kacs_set_sd runs a live one: an O_PATH descriptor with AT_EMPTY_PATH, a pidfd, a token descriptor with AT_EMPTY_PATH, or a path. On those paths it grants every requested right, WRITE_OWNER, WRITE_DAC and ACCESS_SYSTEM_SECURITY included.

Called on an ordinary file descriptor the required rights are checked against the cached mask instead, no AccessCheck runs, and the privilege has no effect at all. A caller needing the bypass has to use the O_PATH route — which is the mechanism behind backup restoration, administrative repair, and the missing-descriptor repair path (§3.9.5).

3.9.6.4 Mandatory resource attributes #

When a caller modifies the SACL, the existing and new SACLs are compared for changes to SYSTEM_RESOURCE_ATTRIBUTE_ACE entries. An existing attribute carrying CLAIM_SECURITY_ATTRIBUTE_MANDATORY (0x0020) cannot be removed, nor its values modified, without SeTcbPrivilege — and an attempt without it fails the entire call rather than silently dropping the change.

3.9.6.5 Write mechanics #

The updated descriptor is serialised to self-relative binary form and written to the xattr through an internal kernel path bypassing the denial hook, and the in-memory cache is updated. An audit event is emitted if the file's SACL carries a matching audit ACE.

The cache update is not atomic with the xattr write; §3.9.5 describes the lock ordering that forces this and the last-writer-wins window it produces.

Edit this page