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 at most 65,535 bytes) then merges only the indicated components into the existing SD. Unindicated components are preserved unchanged.
The input blob is always one self-relative SD subset, not a raw SID or ACL
fragment. SACL_SECURITY_INFORMATION and LABEL_SECURITY_INFORMATION MUST NOT
be combined in one call because they both target the descriptor's SACL field
with incompatible meanings.
When SACL_SECURITY_INFORMATION is set, the input SACL replaces the object's
entire SACL.
When LABEL_SECURITY_INFORMATION is set, the input SACL is interpreted as the
label subset only:
- no SACL component removes the object's explicit mandatory label and returns it to the default unlabeled MIC state;
- a present SACL MUST contain exactly one non-inherit-only
SYSTEM_MANDATORY_LABEL_ACEand no other ACEs; - non-label SACL ACEs on the object are preserved unchanged.
After merging, the resulting SD MUST still have a non-null owner. The group SID MAY be null. If the merge would produce an SD without an owner, the call 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
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, via token fd + AT_EMPTY_PATH, 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.
§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.