On this page
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:
- Serialize the updated SD to self-relative binary format.
- Write the appropriate xattr via an internal kernel path that bypasses the setxattr denial hook.
- Update the in-memory SD cache in the same operation.
- 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.