TS-3145: minimally enhance ElevateAccess for different privileges ElevateAccess only elevates the file access privilege. Add an explicit notion of privilege so that we can use capabilities to elevate other kinds of privilege (specifically, process tracing).
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/d27b31b6 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/d27b31b6 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/d27b31b6 Branch: refs/heads/master Commit: d27b31b63d09f23ac6b6104d0ceaa68832da8c3d Parents: 1906c8b Author: James Peach <[email protected]> Authored: Tue Oct 7 09:13:03 2014 -0700 Committer: James Peach <[email protected]> Committed: Sat Oct 18 12:24:19 2014 -0700 ---------------------------------------------------------------------- lib/ts/ink_cap.cc | 30 +++++++++++++++++++++--------- lib/ts/ink_cap.h | 10 +++++++++- 2 files changed, 30 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d27b31b6/lib/ts/ink_cap.cc ---------------------------------------------------------------------- diff --git a/lib/ts/ink_cap.cc b/lib/ts/ink_cap.cc index 228d027..e49ec6f 100644 --- a/lib/ts/ink_cap.cc +++ b/lib/ts/ink_cap.cc @@ -327,16 +327,28 @@ EnableDeathSignal(int signum) best to program defensively and have it available. */ static void -elevateFileAccess(bool state) +elevateFileAccess(unsigned level, bool state) { Debug("privileges", "[elevateFileAccess] state : %d\n", state); cap_t cap_state = cap_get_proc(); // current capabilities - // Make a list of the capabilities we changed. - cap_value_t cap_list[] = { CAP_DAC_OVERRIDE }; - static int const CAP_COUNT = sizeof(cap_list)/sizeof(*cap_list); - cap_set_flag(cap_state, CAP_EFFECTIVE, CAP_COUNT, cap_list, state ? CAP_SET : CAP_CLEAR); + unsigned cap_count = 0; + cap_value_t cap_list[2]; + + if (level & ElevateAccess::FILE_PRIVILEGE) { + cap_list[cap_count] = CAP_DAC_OVERRIDE; + ++cap_count; + } + + if (level & ElevateAccess::TRACE_PRIVILEGE) { + cap_list[cap_count] = CAP_SYS_PTRACE; + ++cap_count; + } + + ink_release_assert(cap_count <= sizeof(cap_list)); + + cap_set_flag(cap_state, CAP_EFFECTIVE, cap_count, cap_list, state ? CAP_SET : CAP_CLEAR); if (cap_set_proc(cap_state) != 0) { Fatal("failed to %s privileged capabilities: %s", state ? "acquire" : "release", strerror(errno)); } @@ -345,8 +357,8 @@ elevateFileAccess(bool state) } #endif -ElevateAccess::ElevateAccess(const bool state) - : elevated(false), saved_uid(geteuid()) +ElevateAccess::ElevateAccess(const bool state, unsigned lvl) + : elevated(false), saved_uid(geteuid()), level(lvl) { if (state == true) { elevate(); @@ -372,7 +384,7 @@ void ElevateAccess::elevate() { #if TS_USE_POSIX_CAP - elevateFileAccess(true); + elevateFileAccess(level, true); #else // Since we are setting a process-wide credential, we have to block any other thread // attempting to elevate until this one demotes. @@ -386,7 +398,7 @@ void ElevateAccess::demote() { #if TS_USE_POSIX_CAP - elevateFileAccess(false); + elevateFileAccess(level, false); #else ImpersonateUserID(saved_uid, IMPERSONATE_EFFECTIVE); ink_mutex_release(&lock); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d27b31b6/lib/ts/ink_cap.h ---------------------------------------------------------------------- diff --git a/lib/ts/ink_cap.h b/lib/ts/ink_cap.h index 344c5fe..f763316 100644 --- a/lib/ts/ink_cap.h +++ b/lib/ts/ink_cap.h @@ -56,7 +56,13 @@ void ImpersonateUserID(uid_t user, ImpersonationLevel level); class ElevateAccess { public: - ElevateAccess(const bool state); + + typedef enum { + FILE_PRIVILEGE = 0x1u, // Access filesystem objects with privilege + TRACE_PRIVILEGE = 0x2u // Trace other processes with privilege + } privilege_level; + + ElevateAccess(const bool state, unsigned level = FILE_PRIVILEGE); ~ElevateAccess(); void elevate(); @@ -65,6 +71,8 @@ public: private: bool elevated; uid_t saved_uid; + unsigned level; + #if !TS_USE_POSIX_CAP static ink_mutex lock; // only one thread at a time can elevate #endif
