You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2016/01/17 01:42:51 UTC
[1/2] trafficserver git commit: TS-4134: Fix privilege elevation
issues.
Repository: trafficserver
Updated Branches:
refs/heads/6.1.x 3ffd31632 -> 4db4a5262
TS-4134: Fix privilege elevation issues.
This closes #425.
(cherry picked from commit 2c1bdddc5e0946ef2fca0d821603e03f3d19cef2)
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/d54c2f19
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/d54c2f19
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/d54c2f19
Branch: refs/heads/6.1.x
Commit: d54c2f199e5e1a431fbd230d324b80cd3db360f9
Parents: 3ffd316
Author: Alan M. Carroll <am...@apache.org>
Authored: Thu Jan 14 19:28:44 2016 -0600
Committer: Leif Hedstrom <zw...@apache.org>
Committed: Sat Jan 16 17:37:43 2016 -0700
----------------------------------------------------------------------
iocore/net/SSLUtils.cc | 4 +-
lib/ts/BaseLogFile.cc | 7 +--
lib/ts/Diags.cc | 7 +--
lib/ts/ink_cap.cc | 97 +++++++++++++++++++++++++-----------
lib/ts/ink_cap.h | 23 +++++++--
mgmt/LocalManager.cc | 3 +-
mgmt/Rollback.cc | 4 +-
proxy/Main.cc | 18 -------
proxy/Plugin.cc | 4 +-
proxy/http/remap/RemapConfig.cc | 4 +-
10 files changed, 100 insertions(+), 71 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/iocore/net/SSLUtils.cc
----------------------------------------------------------------------
diff --git a/iocore/net/SSLUtils.cc b/iocore/net/SSLUtils.cc
index 0231a15..649fda1 100644
--- a/iocore/net/SSLUtils.cc
+++ b/iocore/net/SSLUtils.cc
@@ -1874,12 +1874,10 @@ SSLParseCertificateConfiguration(const SSLConfigParams *params, SSLCertLookup *l
return false;
}
-#if TS_USE_POSIX_CAP
// elevate/allow file access to root read only files/certs
uint32_t elevate_setting = 0;
REC_ReadConfigInteger(elevate_setting, "proxy.config.ssl.cert.load_elevated");
- ElevateAccess elevate_access(elevate_setting != 0); // destructor will demote for us
-#endif /* TS_USE_POSIX_CAP */
+ ElevateAccess elevate_access(elevate_setting ? ElevateAccess::FILE_PRIVILEGE : 0); // destructor will demote for us
line = tokLine(file_buf, &tok_state);
while (line != NULL) {
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/lib/ts/BaseLogFile.cc
----------------------------------------------------------------------
diff --git a/lib/ts/BaseLogFile.cc b/lib/ts/BaseLogFile.cc
index f134269..349da82 100644
--- a/lib/ts/BaseLogFile.cc
+++ b/lib/ts/BaseLogFile.cc
@@ -323,7 +323,8 @@ BaseLogFile::open_file(int perm)
// open actual log file (not metainfo)
log_log_trace("BaseLogFile: attempting to open %s\n", m_name.get());
- m_fp = fopen(m_name.get(), "a+");
+
+ m_fp = elevating_fopen(m_name.get(), "a+");
// error check
if (m_fp) {
@@ -478,7 +479,7 @@ void
BaseMetaInfo::_read_from_file()
{
_flags |= DATA_FROM_METAFILE; // mark attempt
- int fd = open(_filename, O_RDONLY);
+ int fd = elevating_open(_filename, O_RDONLY);
if (fd < 0) {
log_log_error("Could not open metafile %s for reading: %s\n", _filename, strerror(errno));
} else {
@@ -522,7 +523,7 @@ BaseMetaInfo::_read_from_file()
void
BaseMetaInfo::_write_to_file()
{
- int fd = open(_filename, O_WRONLY | O_CREAT | O_TRUNC, LOGFILE_DEFAULT_PERMS);
+ int fd = elevating_open(_filename, O_WRONLY | O_CREAT | O_TRUNC, LOGFILE_DEFAULT_PERMS);
if (fd < 0) {
log_log_error("Could not open metafile %s for writing: %s\n", _filename, strerror(errno));
return;
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/lib/ts/Diags.cc
----------------------------------------------------------------------
diff --git a/lib/ts/Diags.cc b/lib/ts/Diags.cc
index 7e5747b..cda43b0 100644
--- a/lib/ts/Diags.cc
+++ b/lib/ts/Diags.cc
@@ -821,9 +821,6 @@ Diags::set_stdout_output(const char *_bind_stdout)
stdout_log = NULL;
}
- // get root
- ElevateAccess elevate;
-
// create backing BaseLogFile for stdout
stdout_log = new BaseLogFile(_bind_stdout);
@@ -860,9 +857,7 @@ Diags::set_stderr_output(const char *_bind_stderr)
delete stderr_log;
stderr_log = NULL;
}
- // get root
- ElevateAccess elevate;
-
+
// create backing BaseLogFile for stdout
stderr_log = new BaseLogFile(_bind_stderr);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/lib/ts/ink_cap.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_cap.cc b/lib/ts/ink_cap.cc
index 01e5d5e..625903d 100644
--- a/lib/ts/ink_cap.cc
+++ b/lib/ts/ink_cap.cc
@@ -307,37 +307,74 @@ EnableDeathSignal(int signum)
#endif
}
+int
+elevating_open(char const *path, unsigned int flags, unsigned int fperms)
+{
+ int fd = open(path, flags, fperms);
+ if (fd < 0 && (EPERM == errno || EACCES == errno)) {
+ ElevateAccess access(ElevateAccess::FILE_PRIVILEGE);
+ fd = open(path, flags, fperms);
+ }
+ return fd;
+}
+
+int
+elevating_open(char const *path, unsigned int flags)
+{
+ int fd = open(path, flags);
+ if (fd < 0 && (EPERM == errno || EACCES == errno)) {
+ ElevateAccess access(ElevateAccess::FILE_PRIVILEGE);
+ fd = open(path, flags);
+ }
+ return fd;
+}
+
+FILE*
+elevating_fopen(char const *path, const char* mode)
+{
+ FILE* f = fopen(path, mode);
+ if (NULL == f && (EPERM == errno || EACCES == errno)) {
+ ElevateAccess access(ElevateAccess::FILE_PRIVILEGE);
+ f = fopen(path, mode);
+ }
+ return f;
+}
+
#if TS_USE_POSIX_CAP
/** Acquire file access privileges to bypass DAC.
@a level is a mask of the specific file access capabilities to acquire.
*/
void
-ElevateAccess::acquireFileAccessCap(unsigned level)
+ElevateAccess::acquirePrivilege(unsigned priv_mask)
{
unsigned cap_count = 0;
cap_value_t cap_list[2];
cap_t new_cap_state;
- Debug("privileges", "[acquireFileAccessCap] level= %x\n", level);
+ Debug("privileges", "[acquirePrivilege] level= %x\n", level);
ink_assert(NULL == cap_state);
- if (level) {
- this->cap_state = cap_get_proc(); // save current capabilities
- new_cap_state = cap_get_proc(); // and another instance to modify.
+ // Some privs aren't checked or used here because they are kept permanently in the
+ // the capability list. See @a eff_list in @c RestrictCapabilities
+ // It simplifies things elsewhere to be able to specify them so that the cases for
+ // POSIX capabilities and user impersonation have the same interface.
- if (level & ElevateAccess::FILE_PRIVILEGE) {
- cap_list[cap_count] = CAP_DAC_OVERRIDE;
- ++cap_count;
- }
+ if (priv_mask & 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;
- }
+ if (priv_mask & ElevateAccess::TRACE_PRIVILEGE) {
+ cap_list[cap_count] = CAP_SYS_PTRACE;
+ ++cap_count;
+ }
- ink_release_assert(cap_count <= sizeof(cap_list));
+ ink_release_assert(cap_count <= sizeof(cap_list));
+ if (cap_count > 0) {
+ this->cap_state = cap_get_proc(); // save current capabilities
+ new_cap_state = cap_get_proc(); // and another instance to modify.
cap_set_flag(new_cap_state, CAP_EFFECTIVE, cap_count, cap_list, CAP_SET);
if (cap_set_proc(new_cap_state) != 0) {
@@ -345,12 +382,13 @@ ElevateAccess::acquireFileAccessCap(unsigned level)
}
cap_free(new_cap_state);
+ elevated = true;
}
}
/** Restore previous capabilities.
*/
void
-ElevateAccess::releaseFileAccessCap()
+ElevateAccess::releasePrivilege()
{
Debug("privileges", "[releaseFileAccessCap]");
@@ -379,7 +417,7 @@ ElevateAccess::ElevateAccess(unsigned lvl)
ElevateAccess::~ElevateAccess()
{
- if (elevated == true) {
+ if (elevated) {
demote();
#if !TS_USE_POSIX_CAP
DEBUG_CREDENTIALS("privileges");
@@ -389,28 +427,31 @@ ElevateAccess::~ElevateAccess()
}
void
-ElevateAccess::elevate(unsigned level)
+ElevateAccess::elevate(unsigned priv_mask)
{
#if TS_USE_POSIX_CAP
- acquireFileAccessCap(level);
+ acquirePrivilege(priv_mask);
#else
- (void)level;
- // Since we are setting a process-wide credential, we have to block any other thread
- // attempting to elevate until this one demotes.
- ink_mutex_acquire(&lock);
- ImpersonateUserID(0, IMPERSONATE_EFFECTIVE);
+ if (priv_mask) {
+ // Since we are setting a process-wide credential, we have to block any other thread
+ // attempting to elevate until this one demotes.
+ ink_mutex_acquire(&lock);
+ ImpersonateUserID(0, IMPERSONATE_EFFECTIVE);
+ elevated = true;
+ }
#endif
- elevated = true;
}
void
ElevateAccess::demote()
{
+ if (elevated) {
#if TS_USE_POSIX_CAP
- releaseFileAccessCap();
+ releasePrivilege();
#else
- ImpersonateUserID(saved_uid, IMPERSONATE_EFFECTIVE);
- ink_mutex_release(&lock);
+ ImpersonateUserID(saved_uid, IMPERSONATE_EFFECTIVE);
+ ink_mutex_release(&lock);
#endif
- elevated = false;
+ elevated = false;
+ }
}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/lib/ts/ink_cap.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_cap.h b/lib/ts/ink_cap.h
index 19e94a4..0978965 100644
--- a/lib/ts/ink_cap.h
+++ b/lib/ts/ink_cap.h
@@ -38,6 +38,18 @@ extern bool PreserveCapabilities();
/// Initialize and restrict the capabilities of a thread.
/// @return true on success
extern bool RestrictCapabilities();
+/** Open a file, elevating privilege only if needed.
+
+ @internal This is necessary because the CI machines run the regression tests
+ as a normal user, not as root, so attempts to get privilege fail even though
+ the @c open would succeed without elevation. So, try that first and ask for
+ elevation only on an explicit permission failure.
+*/
+extern int elevating_open(char const *path, unsigned int flags, unsigned int fperms);
+/// Open a file, elevating privilege only if needed.
+extern int elevating_open(char const *path, unsigned int flags);
+/// Open a file, elevating privilege only if needed.
+extern FILE* elevating_fopen(char const *path, const char* mode);
/** Control generate of core file on crash.
@a flag sets whether core files are enabled on crash.
@@ -60,8 +72,9 @@ class ElevateAccess
{
public:
typedef enum {
- FILE_PRIVILEGE = 0x1u, // Access filesystem objects with privilege
- TRACE_PRIVILEGE = 0x2u // Trace other processes with privilege
+ FILE_PRIVILEGE = 0x1u, ///< Access filesystem objects with privilege
+ TRACE_PRIVILEGE = 0x2u, ///< Trace other processes with privilege
+ LOW_PORT_PRIVILEGE = 0x4u ///< Bind to privilege ports.
} privilege_level;
ElevateAccess(unsigned level = FILE_PRIVILEGE);
@@ -75,8 +88,10 @@ private:
uid_t saved_uid;
unsigned level;
- void acquireFileAccessCap(unsigned level);
- void releaseFileAccessCap();
+ /// Acquire the privileges marked in @a mask for this process.
+ void acquirePrivilege(unsigned priv_mask);
+ /// Restore the privilege set to the state before acquiring them.
+ void releasePrivilege();
#if !TS_USE_POSIX_CAP
static ink_mutex lock; // only one thread at a time can elevate
#else
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/mgmt/LocalManager.cc
----------------------------------------------------------------------
diff --git a/mgmt/LocalManager.cc b/mgmt/LocalManager.cc
index 44cc63b..6036a7b 100644
--- a/mgmt/LocalManager.cc
+++ b/mgmt/LocalManager.cc
@@ -1021,8 +1021,9 @@ void
LocalManager::bindProxyPort(HttpProxyPort &port)
{
int one = 1;
+ int priv = (port.m_port < 1024 && 0 != geteuid()) ? ElevateAccess::LOW_PORT_PRIVILEGE : 0;
- ElevateAccess access(port.m_port < 1024 && geteuid() != 0);
+ ElevateAccess access(priv);
/* Setup reliable connection, for large config changes */
if ((port.m_fd = socket(port.m_family, SOCK_STREAM, 0)) < 0) {
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/mgmt/Rollback.cc
----------------------------------------------------------------------
diff --git a/mgmt/Rollback.cc b/mgmt/Rollback.cc
index 217902c..f1361f4 100644
--- a/mgmt/Rollback.cc
+++ b/mgmt/Rollback.cc
@@ -260,7 +260,7 @@ Rollback::statFile(version_t version, struct stat *buf)
}
ats_scoped_str filePath(createPathStr(version));
- ElevateAccess access(root_access_needed);
+ ElevateAccess access(root_access_needed ? ElevateAccess::FILE_PRIVILEGE : 0);
statResult = stat(filePath, buf);
@@ -278,7 +278,7 @@ Rollback::openFile(version_t version, int oflags, int *errnoPtr)
int fd;
ats_scoped_str filePath(createPathStr(version));
- ElevateAccess access(root_access_needed);
+ ElevateAccess access(root_access_needed ? ElevateAccess::FILE_PRIVILEGE : 0);
// TODO: Use the original permissions
// Anyhow the _1 files should not be created inside Syconfdir.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/proxy/Main.cc
----------------------------------------------------------------------
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 5fc8f86..45881e3 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -1422,24 +1422,6 @@ change_uid_gid(const char *user)
#endif
}
-/** Open a file, elevating privilege only if needed.
-
- @internal This is necessary because the CI machines run the regression tests
- as a normal user, not as root, so attempts to get privilege fail even though
- the @c open would succeed without elevation. So, try that first and ask for
- elevation only on an explicit permission failure.
-*/
-static int
-elevating_open(char const *path, unsigned int flags, unsigned int fperms)
-{
- int fd = open(path, flags, fperms);
- if (fd < 0 && (EPERM == errno || EACCES == errno)) {
- ElevateAccess access;
- fd = open(path, flags, fperms);
- }
- return fd;
-}
-
/*
* Binds stdout and stderr to files specified by the parameters
*
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/proxy/Plugin.cc
----------------------------------------------------------------------
diff --git a/proxy/Plugin.cc b/proxy/Plugin.cc
index a621b92..b7b450c 100644
--- a/proxy/Plugin.cc
+++ b/proxy/Plugin.cc
@@ -94,11 +94,9 @@ plugin_load(int argc, char *argv[], bool validateOnly)
// elevate the access to read files as root if compiled with capabilities, if not
// change the effective user to root
{
-#if TS_USE_POSIX_CAP
uint32_t elevate_access = 0;
REC_ReadConfigInteger(elevate_access, "proxy.config.plugin.load_elevated");
- ElevateAccess access(elevate_access != 0);
-#endif /* TS_USE_POSIX_CAP */
+ ElevateAccess access(elevate_access ? ElevateAccess::FILE_PRIVILEGE : 0);
void *handle = dlopen(path, RTLD_NOW);
if (!handle) {
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d54c2f19/proxy/http/remap/RemapConfig.cc
----------------------------------------------------------------------
diff --git a/proxy/http/remap/RemapConfig.cc b/proxy/http/remap/RemapConfig.cc
index 4a0e850..8b5f58e 100644
--- a/proxy/http/remap/RemapConfig.cc
+++ b/proxy/http/remap/RemapConfig.cc
@@ -760,11 +760,9 @@ remap_load_plugin(const char **argv, int argc, url_mapping *mp, char *errbuf, in
Debug("remap_plugin", "New remap plugin info created for \"%s\"", c);
{
-#if TS_USE_POSIX_CAP
uint32_t elevate_access = 0;
REC_ReadConfigInteger(elevate_access, "proxy.config.plugin.load_elevated");
- ElevateAccess access(elevate_access != 0);
-#endif /* TS_USE_POSIX_CAP */
+ ElevateAccess access(elevate_access ? ElevateAccess::FILE_PRIVILEGE : 0);
if ((pi->dlh = dlopen(c, RTLD_NOW)) == NULL) {
#if defined(freebsd) || defined(openbsd)
[2/2] trafficserver git commit: TS-4134 Fixes clang-format
Posted by zw...@apache.org.
TS-4134 Fixes clang-format
(cherry picked from commit 93852b454e705e9363ddf81e04a36aa0d3b6938a)
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/4db4a526
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/4db4a526
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/4db4a526
Branch: refs/heads/6.1.x
Commit: 4db4a5262898e6ec59e2065931476a4feecd2526
Parents: d54c2f1
Author: Leif Hedstrom <zw...@apache.org>
Authored: Sat Jan 16 17:42:14 2016 -0700
Committer: Leif Hedstrom <zw...@apache.org>
Committed: Sat Jan 16 17:42:37 2016 -0700
----------------------------------------------------------------------
lib/ts/Diags.cc | 2 +-
lib/ts/ink_cap.cc | 6 +++---
lib/ts/ink_cap.h | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/4db4a526/lib/ts/Diags.cc
----------------------------------------------------------------------
diff --git a/lib/ts/Diags.cc b/lib/ts/Diags.cc
index cda43b0..28d6b91 100644
--- a/lib/ts/Diags.cc
+++ b/lib/ts/Diags.cc
@@ -857,7 +857,7 @@ Diags::set_stderr_output(const char *_bind_stderr)
delete stderr_log;
stderr_log = NULL;
}
-
+
// create backing BaseLogFile for stdout
stderr_log = new BaseLogFile(_bind_stderr);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/4db4a526/lib/ts/ink_cap.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_cap.cc b/lib/ts/ink_cap.cc
index 625903d..23c6f83 100644
--- a/lib/ts/ink_cap.cc
+++ b/lib/ts/ink_cap.cc
@@ -329,10 +329,10 @@ elevating_open(char const *path, unsigned int flags)
return fd;
}
-FILE*
-elevating_fopen(char const *path, const char* mode)
+FILE *
+elevating_fopen(char const *path, const char *mode)
{
- FILE* f = fopen(path, mode);
+ FILE *f = fopen(path, mode);
if (NULL == f && (EPERM == errno || EACCES == errno)) {
ElevateAccess access(ElevateAccess::FILE_PRIVILEGE);
f = fopen(path, mode);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/4db4a526/lib/ts/ink_cap.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_cap.h b/lib/ts/ink_cap.h
index 0978965..fd93a60 100644
--- a/lib/ts/ink_cap.h
+++ b/lib/ts/ink_cap.h
@@ -49,7 +49,7 @@ extern int elevating_open(char const *path, unsigned int flags, unsigned int fpe
/// Open a file, elevating privilege only if needed.
extern int elevating_open(char const *path, unsigned int flags);
/// Open a file, elevating privilege only if needed.
-extern FILE* elevating_fopen(char const *path, const char* mode);
+extern FILE *elevating_fopen(char const *path, const char *mode);
/** Control generate of core file on crash.
@a flag sets whether core files are enabled on crash.