Skip to content

tmpfs: Clear security.capability xattr on write#13072

Merged
copybara-service[bot] merged 1 commit intogoogle:masterfrom
shayonj:fix-cap-survive-write
May 7, 2026
Merged

tmpfs: Clear security.capability xattr on write#13072
copybara-service[bot] merged 1 commit intogoogle:masterfrom
shayonj:fix-cap-survive-write

Conversation

@shayonj
Copy link
Copy Markdown
Contributor

@shayonj shayonj commented May 4, 2026

When a non-privileged user writes to a file on tmpfs, Linux clears both the setuid/setgid mode bits and the security.capability xattr via file_remove_privs. The mode bit clearing was already implemented through ClearSUIDAndSGID in the pwrite path, but the xattr removal was missing, so file capabilities survived content replacement. An unprivileged user could overwrite a capability-bearing binary and execute it with the retained privileges.

The fix adds a KillPriv method on SimpleExtendedAttributes that removes security.capability without permission checks (matching Linux's cap_inode_killpriv, where the kernel is the actor), and calls it from the tmpfs pwrite path alongside the existing ClearSUIDAndSGID.

The gofer filesystem is not affected because it explicitly blocks security.* xattr writes to the host filesystem.

Fixes #13063

Comment thread pkg/sentry/vfs/memxattr/xattr.go Outdated
@ayushr2 ayushr2 requested a review from shailend-g May 4, 2026 20:54
@shayonj shayonj force-pushed the fix-cap-survive-write branch from 47d878d to 2878793 Compare May 4, 2026 20:55
Comment thread pkg/sentry/fsimpl/tmpfs/regular_file.go
Copy link
Copy Markdown
Contributor

@shailend-g shailend-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the patch! Please consider removing the file caps in the chown() and truncate() paths as well, see ClearPrivs in vfs.SetStatOptions.

@shayonj shayonj force-pushed the fix-cap-survive-write branch from 2878793 to 197b5ef Compare May 5, 2026 22:15
When a non-privileged user writes to a file on tmpfs, Linux clears both
the setuid/setgid mode bits and the security.capability xattr via
file_remove_privs. The mode bit clearing was already implemented through
ClearSUIDAndSGID, but the xattr removal was missing, so file
capabilities survived content replacement. An unprivileged user could
overwrite a capability-bearing binary and execute it with the retained
privileges.

Fixes google#13063
@shayonj shayonj force-pushed the fix-cap-survive-write branch from 197b5ef to 72063bf Compare May 6, 2026 01:25
copybara-service Bot pushed a commit that referenced this pull request May 7, 2026
When a non-privileged user writes to a file on tmpfs, Linux clears both the setuid/setgid mode bits and the `security.capability` xattr via `file_remove_privs`. The mode bit clearing was already implemented through `ClearSUIDAndSGID` in the pwrite path, but the xattr removal was missing, so file capabilities survived content replacement. An unprivileged user could overwrite a capability-bearing binary and execute it with the retained privileges.

The fix adds a `KillPriv` method on `SimpleExtendedAttributes` that removes `security.capability` without permission checks (matching Linux's `cap_inode_killpriv`, where the kernel is the actor), and calls it from the tmpfs pwrite path alongside the existing `ClearSUIDAndSGID`.

The gofer filesystem is not affected because it explicitly blocks `security.*` xattr writes to the host filesystem.

Fixes #13063

FUTURE_COPYBARA_INTEGRATE_REVIEW=#13072 from shayonj:fix-cap-survive-write 72063bf
PiperOrigin-RevId: 911628845
copybara-service Bot pushed a commit that referenced this pull request May 7, 2026
When a non-privileged user writes to a file on tmpfs, Linux clears both the setuid/setgid mode bits and the `security.capability` xattr via `file_remove_privs`. The mode bit clearing was already implemented through `ClearSUIDAndSGID` in the pwrite path, but the xattr removal was missing, so file capabilities survived content replacement. An unprivileged user could overwrite a capability-bearing binary and execute it with the retained privileges.

The fix adds a `KillPriv` method on `SimpleExtendedAttributes` that removes `security.capability` without permission checks (matching Linux's `cap_inode_killpriv`, where the kernel is the actor), and calls it from the tmpfs pwrite path alongside the existing `ClearSUIDAndSGID`.

The gofer filesystem is not affected because it explicitly blocks `security.*` xattr writes to the host filesystem.

Fixes #13063

FUTURE_COPYBARA_INTEGRATE_REVIEW=#13072 from shayonj:fix-cap-survive-write 72063bf
PiperOrigin-RevId: 911628845
copybara-service Bot pushed a commit that referenced this pull request May 7, 2026
When a non-privileged user writes to a file on tmpfs, Linux clears both the setuid/setgid mode bits and the `security.capability` xattr via `file_remove_privs`. The mode bit clearing was already implemented through `ClearSUIDAndSGID` in the pwrite path, but the xattr removal was missing, so file capabilities survived content replacement. An unprivileged user could overwrite a capability-bearing binary and execute it with the retained privileges.

The fix adds a `KillPriv` method on `SimpleExtendedAttributes` that removes `security.capability` without permission checks (matching Linux's `cap_inode_killpriv`, where the kernel is the actor), and calls it from the tmpfs pwrite path alongside the existing `ClearSUIDAndSGID`.

The gofer filesystem is not affected because it explicitly blocks `security.*` xattr writes to the host filesystem.

Fixes #13063

FUTURE_COPYBARA_INTEGRATE_REVIEW=#13072 from shayonj:fix-cap-survive-write 72063bf
PiperOrigin-RevId: 911628845
Comment thread test/syscalls/linux/chown.cc
Comment thread test/syscalls/linux/xattr.cc
copybara-service Bot pushed a commit that referenced this pull request May 7, 2026
When a non-privileged user writes to a file on tmpfs, Linux clears both the setuid/setgid mode bits and the `security.capability` xattr via `file_remove_privs`. The mode bit clearing was already implemented through `ClearSUIDAndSGID` in the pwrite path, but the xattr removal was missing, so file capabilities survived content replacement. An unprivileged user could overwrite a capability-bearing binary and execute it with the retained privileges.

The fix adds a `KillPriv` method on `SimpleExtendedAttributes` that removes `security.capability` without permission checks (matching Linux's `cap_inode_killpriv`, where the kernel is the actor), and calls it from the tmpfs pwrite path alongside the existing `ClearSUIDAndSGID`.

The gofer filesystem is not affected because it explicitly blocks `security.*` xattr writes to the host filesystem.

Fixes #13063

FUTURE_COPYBARA_INTEGRATE_REVIEW=#13072 from shayonj:fix-cap-survive-write 72063bf
PiperOrigin-RevId: 911628845
@copybara-service copybara-service Bot merged commit d4d9d66 into google:master May 7, 2026
3 checks passed
copybara-service Bot pushed a commit that referenced this pull request May 7, 2026
Follow-up to #13072. The internal linter was blocking submit because chown.cc uses std::string without directly including <string>, and ayushr2 flagged that both test files were defining VFS_CAP_REVISION_2 and VFS_CAP_FLAGS_EFFECTIVE as raw hex literals instead of using the constants from linux/capability.h.

This adds the missing include and replaces the magic numbers in both chown.cc and xattr.cc.

FUTURE_COPYBARA_INTEGRATE_REVIEW=#13115 from shayonj:fix-cap-constants f6bb91b
PiperOrigin-RevId: 912098808
copybara-service Bot pushed a commit that referenced this pull request May 7, 2026
Follow-up to #13072. The internal linter was blocking submit because chown.cc uses std::string without directly including <string>, and ayushr2 flagged that both test files were defining VFS_CAP_REVISION_2 and VFS_CAP_FLAGS_EFFECTIVE as raw hex literals instead of using the constants from linux/capability.h.

This adds the missing include and replaces the magic numbers in both chown.cc and xattr.cc.

FUTURE_COPYBARA_INTEGRATE_REVIEW=#13115 from shayonj:fix-cap-constants f6bb91b
PiperOrigin-RevId: 912098808
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File Capabilities Survive Non-Root Rewrite

3 participants