This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new eeb4600d1d Add CAP_CHOWN to permitted capability set (#12908)
eeb4600d1d is described below

commit eeb4600d1dc03052699403893a62e6f04d189af3
Author: Bryan Call <[email protected]>
AuthorDate: Wed Mar 18 12:17:41 2026 -0700

    Add CAP_CHOWN to permitted capability set (#12908)
    
    Add CAP_CHOWN support to ATS privilege elevation path
    
    Retain `CAP_CHOWN` in the permitted capability set after privilege drop
    so plugins can set ownership on cert-related backup files (e.g. root:root
    600 workflows). As with `CAP_DAC_OVERRIDE`, this remains permitted-only
    and must be explicitly raised to effective before use.
    
    Add `CHOWN_PRIVILEGE` (`0x10u`) to `ElevateAccess::privilege_level` and
    wire it through `acquirePrivilege()` so plugins can request ownership
    elevation via the standard ATS privilege API.
    
    Also fix the `acquirePrivilege()` bounds assertion to compare against
    array element count (not byte size).
---
 include/tscore/ink_cap.h |  4 ++--
 src/tscore/ink_cap.cc    | 11 ++++++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/include/tscore/ink_cap.h b/include/tscore/ink_cap.h
index 86a8f31f4d..a18c3449ac 100644
--- a/include/tscore/ink_cap.h
+++ b/include/tscore/ink_cap.h
@@ -81,8 +81,8 @@ public:
     FILE_PRIVILEGE     = 0x1u, ///< Access filesystem objects with privilege
     TRACE_PRIVILEGE    = 0x2u, ///< Trace other processes with privilege
     LOW_PORT_PRIVILEGE = 0x4u, ///< Bind to privilege ports.
-    OWNER_PRIVILEGE    = 0x8u  ///< Bypass permission checks on operations 
that normally require
-                               ///  filesystem UID & process UID to match
+    OWNER_PRIVILEGE    = 0x8u, ///< Owner-only operations on unowned files 
(CAP_FOWNER)
+    CHOWN_PRIVILEGE    = 0x10u ///< Change file ownership
   };
 
   ElevateAccess(unsigned level = FILE_PRIVILEGE);
diff --git a/src/tscore/ink_cap.cc b/src/tscore/ink_cap.cc
index f464daad3b..1e208f34cf 100644
--- a/src/tscore/ink_cap.cc
+++ b/src/tscore/ink_cap.cc
@@ -273,7 +273,7 @@ RestrictCapabilities()
   cap_t caps_orig = cap_get_proc();
 
   // 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};
   static int const PERM_CAP_COUNT = sizeof(perm_list) / sizeof(*perm_list);
   cap_value_t      eff_list[]     = {CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, 
CAP_IPC_LOCK};
   static int const EFF_CAP_COUNT  = sizeof(eff_list) / sizeof(*eff_list);
@@ -436,7 +436,7 @@ void
 ElevateAccess::acquirePrivilege(unsigned priv_mask)
 {
   unsigned    cap_count = 0;
-  cap_value_t cap_list[3];
+  cap_value_t cap_list[4];
   cap_t       new_cap_state;
 
   Dbg(dbg_ctl_privileges, "[acquirePrivilege] level= %x", level);
@@ -463,7 +463,12 @@ ElevateAccess::acquirePrivilege(unsigned priv_mask)
     ++cap_count;
   }
 
-  ink_release_assert(cap_count <= sizeof(cap_list));
+  if (priv_mask & ElevateAccess::CHOWN_PRIVILEGE) {
+    cap_list[cap_count] = CAP_CHOWN;
+    ++cap_count;
+  }
+
+  ink_release_assert(cap_count <= sizeof(cap_list) / sizeof(cap_list[0]));
 
   if (cap_count > 0) {
     this->cap_state = cap_get_proc(); // save current capabilities

Reply via email to