Skip to content

Comments

Add CAP_CHOWN to permitted capability set#12908

Open
bryancall wants to merge 1 commit intoapache:masterfrom
bryancall:add-cap-chown-to-permitted
Open

Add CAP_CHOWN to permitted capability set#12908
bryancall wants to merge 1 commit intoapache:masterfrom
bryancall:add-cap-chown-to-permitted

Conversation

@bryancall
Copy link
Contributor

Summary

Add CAP_CHOWN to the permitted capability set retained by RestrictCapabilities() after the privilege drop from root to the unprivileged user.

This enables plugins that manage TLS certificate files to set root:root ownership on backup copies they write to disk, supporting deployments where cert files are restricted to root:root 600 inside root:root 700 directories.

Changes

  • src/tscore/ink_cap.cc -- Added CAP_CHOWN to perm_list in RestrictCapabilities(). Like CAP_DAC_OVERRIDE and CAP_FOWNER, it is retained in the permitted set only (not effective). A plugin must explicitly promote it to the effective set before use.

Security Considerations

CAP_CHOWN allows changing file ownership. It follows the same security model as CAP_DAC_OVERRIDE (already retained): held in the permitted set but not in the effective set during normal operation. A plugin must use RAII-style elevation to briefly promote it, then drop it immediately after the fchown() call.

Testing

Verified on Fedora 43 with libcap 2.76:

  • CAP_CHOWN appears in CapPrm but not CapEff after startup
  • fchown() succeeds when the capability is elevated
  • No change to steady-state behavior

Add CAP_CHOWN to the permitted capability set retained after privilege
drop. This allows plugins that perform cert file backup writes to set
root ownership on newly created files when certs are restricted to
root:root 600.

Like CAP_DAC_OVERRIDE, CAP_CHOWN is held in the permitted set only and
must be explicitly promoted to the effective set before use. It is not
active during normal operation.
@bryancall bryancall added this to the 10.2.0 milestone Feb 23, 2026
@bryancall bryancall self-assigned this Feb 23, 2026
@bryancall bryancall modified the milestones: 10.2.0, 11.0.0 Feb 23, 2026
@bryancall bryancall requested a review from Copilot February 23, 2026 21:30
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds CAP_CHOWN to the permitted capability set to enable plugins to change file ownership, specifically to support TLS certificate management plugins that need to set root:root ownership on backup certificate files.

Changes:

  • Added CAP_CHOWN to the perm_list array in RestrictCapabilities(), making it available in the permitted set (but not the effective set) after privilege drop


// Capabilities we need.
cap_value_t perm_list[] = {CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK, CAP_DAC_OVERRIDE, CAP_FOWNER};
cap_value_t perm_list[] = {CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_CHOWN};
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

Adding CAP_CHOWN to the permitted set without a corresponding privilege level in the ElevateAccess class makes it effectively unusable. Currently, ElevateAccess supports FILE_PRIVILEGE (maps to CAP_DAC_OVERRIDE), OWNER_PRIVILEGE (maps to CAP_FOWNER), TRACE_PRIVILEGE (maps to CAP_SYS_PTRACE), and LOW_PORT_PRIVILEGE. To actually use CAP_CHOWN, you need to either:

  1. Add a new privilege level (e.g., CHOWN_PRIVILEGE = 0x10u) to the ElevateAccess class in include/tscore/ink_cap.h
  2. Update the acquirePrivilege() function in src/tscore/ink_cap.cc to handle this new privilege level by elevating CAP_CHOWN to the effective set

Without these changes, CAP_CHOWN will remain in the permitted set but cannot be elevated to the effective set, making it impossible for plugins to use fchown() as described in the PR description.

Suggested change
cap_value_t perm_list[] = {CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_CHOWN};
cap_value_t perm_list[] = {CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK, CAP_DAC_OVERRIDE, CAP_FOWNER};

Copilot uses AI. Check for mistakes.

// Capabilities we need.
cap_value_t perm_list[] = {CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK, CAP_DAC_OVERRIDE, CAP_FOWNER};
cap_value_t perm_list[] = {CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_CHOWN};
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

This line exceeds the maximum line length of 132 characters (currently 143 characters). According to the C++ style guidelines for this repository, lines should not exceed 132 characters. Consider breaking this into multiple lines or using a more compact formatting.

Copilot generated this review using guidance from repository custom instructions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant