You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2013/10/04 00:09:20 UTC
git commit: [TS-2261] Add config option to restore/elevate access to
reading files by root when loading plugins
Updated Branches:
refs/heads/master 4102e9868 -> fffb60ed3
[TS-2261] Add config option to restore/elevate access to reading files by
root when loading plugins
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/fffb60ed
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/fffb60ed
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/fffb60ed
Branch: refs/heads/master
Commit: fffb60ed3bbc30cf302e0ccf956248cb1ec5cef3
Parents: 4102e98
Author: Bryan Call <bc...@apache.org>
Authored: Thu Oct 3 15:08:04 2013 -0700
Committer: Bryan Call <bc...@apache.org>
Committed: Thu Oct 3 15:08:04 2013 -0700
----------------------------------------------------------------------
CHANGES | 3 ++
lib/ts/ink_cap.cc | 81 +++++++++++++++++++++++++++++++++++--
lib/ts/ink_cap.h | 47 +++++++++++++++++++++
mgmt/LocalManager.cc | 65 +----------------------------
mgmt/LocalManager.h | 6 ---
mgmt/RecordsConfig.cc | 3 ++
mgmt/Rollback.cc | 2 +-
proxy/Plugin.cc | 10 ++++-
proxy/http/remap/UrlMapping.cc | 11 ++++-
proxy/http/remap/UrlRewrite.cc | 28 ++++++++++---
10 files changed, 173 insertions(+), 83 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index ee94a4b..cf1bff2 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes with Apache Traffic Server 4.1.0
+ *) [TS-2261] Add config option to restore/elevate access to reading files by
+ root when loading plugins
+
*) [TS-2257] Healthcheck plugin can stop watching some events.
*) [TS-2260] Avoid flooding log when log host is down.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/lib/ts/ink_cap.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_cap.cc b/lib/ts/ink_cap.cc
index 038fc2e..e51b730 100644
--- a/lib/ts/ink_cap.cc
+++ b/lib/ts/ink_cap.cc
@@ -65,6 +65,7 @@ PreserveCapabilities() {
# if TS_USE_POSIX_CAP
zret = prctl(PR_SET_KEEPCAPS, 1);
# endif
+ Debug("proxy_priv", "[PreserveCapabilities] zret : %d\n", zret);
return zret;
}
@@ -75,14 +76,17 @@ RestrictCapabilities() {
# if TS_USE_POSIX_CAP
cap_t caps = cap_init(); // start with nothing.
// Capabilities we need.
- cap_value_t cap_list[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK };
- static int const CAP_COUNT = sizeof(cap_list)/sizeof(*cap_list);
+ cap_value_t perm_list[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE, CAP_IPC_LOCK, CAP_DAC_OVERRIDE};
+ 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);
- cap_set_flag(caps, CAP_PERMITTED, CAP_COUNT, cap_list, CAP_SET);
- cap_set_flag(caps, CAP_EFFECTIVE, CAP_COUNT, cap_list, CAP_SET);
+ cap_set_flag(caps, CAP_PERMITTED, PERM_CAP_COUNT, perm_list, CAP_SET);
+ cap_set_flag(caps, CAP_EFFECTIVE, EFF_CAP_COUNT, eff_list, CAP_SET);
zret = cap_set_proc(caps);
cap_free(caps);
# endif
+ Debug("proxy_priv", "[RestrictCapabilities] zret : %d\n", zret);
return zret;
}
@@ -98,5 +102,74 @@ EnableCoreFile(bool flag) {
Warning("Call to set PR_DUMPABLE was ineffective");
}
# endif // linux check
+ Debug("proxy_priv", "[EnableCoreFile] zret : %d\n", zret);
return zret;
}
+
+#if TS_USE_POSIX_CAP
+/** Control file access privileges to bypass DAC.
+ @parm state Use @c true to enable elevated privileges,
+ @c false to disable.
+ @return @c true if successful, @c false otherwise.
+
+ @internal After some pondering I decided that the file access
+ privilege was worth the effort of restricting. Unlike the network
+ privileges this can protect a host system from programming errors
+ by not (usually) permitting such errors to access arbitrary
+ files. This is particularly true since none of the config files
+ current enable this feature so it's not actually called. Still,
+ best to program defensively and have it available.
+ */
+bool
+elevateFileAccess(bool state)
+{
+ Debug("proxy_priv", "[elevateFileAccess] state : %d\n", state);
+
+ bool zret = false; // return value.
+ 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);
+ zret = (0 == cap_set_proc(cap_state));
+ cap_free(cap_state);
+ Debug("proxy_priv", "[elevateFileAccess] zret : %d\n", zret);
+ return zret;
+}
+#else
+// bool removeRootPriv()
+//
+// - Returns true on success
+// and false on failure
+bool
+removeRootPriv(uid_t euid)
+{
+ if (seteuid(euid) < 0) {
+ Debug("proxy_priv", "[removeRootPriv] seteuid failed : %s\n", strerror(errno));
+ return false;
+ }
+
+ Debug("proxy_priv", "[removeRootPriv] removed root privileges. Euid is %d\n", euid);
+ return true;
+}
+
+// bool restoreRootPriv()
+//
+// - Returns true on success
+// and false on failure
+bool
+restoreRootPriv(uid_t *old_euid)
+{
+ if (old_euid)
+ *old_euid = geteuid();
+ if (seteuid(0) < 0) {
+ Debug("proxy_priv", "[restoreRootPriv] seteuid root failed : %s\n", strerror(errno));
+ return false;
+ }
+
+ Debug("proxy_priv", "[restoreRootPriv] restored root privileges. Euid is %d\n", 0);
+
+ return true;
+}
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/lib/ts/ink_cap.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_cap.h b/lib/ts/ink_cap.h
index a457737..e29acea 100644
--- a/lib/ts/ink_cap.h
+++ b/lib/ts/ink_cap.h
@@ -44,4 +44,51 @@ extern int EnableCoreFile(
bool flag ///< New enable state.
);
+
+
+#if TS_USE_POSIX_CAP
+bool elevateFileAccess(bool);
+#else
+bool restoreRootPriv(uid_t *old_euid = NULL);
+bool removeRootPriv(uid_t euid);
+#endif
+
+
+class ElevateAccess {
+public:
+ ElevateAccess(const bool state): elevated(false), saved_uid(0) {
+ if (state == true) {
+ elevate();
+ }
+ }
+
+ void elevate() {
+#if TS_USE_POSIX_CAP
+ elevateFileAccess(true);
+#else
+ restoreRootPriv(&saved_uid);
+#endif
+ elevated = true;
+ }
+
+ void demote() {
+#if TS_USE_POSIX_CAP
+ elevateFileAccess(false);
+#else
+ removeRootPriv(saved_uid);
+#endif
+ elevated = false;
+ }
+
+ ~ElevateAccess() {
+ if (elevated == true) {
+ demote();
+ }
+ }
+
+private:
+ bool elevated;
+ uid_t saved_uid;
+};
+
#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/mgmt/LocalManager.cc
----------------------------------------------------------------------
diff --git a/mgmt/LocalManager.cc b/mgmt/LocalManager.cc
index 7b2799b..b7feeca 100644
--- a/mgmt/LocalManager.cc
+++ b/mgmt/LocalManager.cc
@@ -29,6 +29,7 @@
#include "Compatability.h"
#include "LocalManager.h"
#include "MgmtSocket.h"
+#include "ink_cap.h"
#if TS_USE_POSIX_CAP
#include <sys/capability.h>
@@ -1084,70 +1085,6 @@ LocalManager::listenForProxy()
return;
}
-#if TS_USE_POSIX_CAP
-/** Control file access privileges to bypass DAC.
- @parm state Use @c true to enable elevated privileges,
- @c false to disable.
- @return @c true if successful, @c false otherwise.
-
- @internal After some pondering I decided that the file access
- privilege was worth the effort of restricting. Unlike the network
- privileges this can protect a host system from programming errors
- by not (usually) permitting such errors to access arbitrary
- files. This is particularly true since none of the config files
- current enable this feature so it's not actually called. Still,
- best to program defensively and have it available.
- */
-bool
-elevateFileAccess(bool state)
-{
- bool zret = false; // return value.
- 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);
- zret = (0 == cap_set_proc(cap_state));
- cap_free(cap_state);
- return zret;
-}
-#else
-// bool removeRootPriv()
-//
-// - Returns true on success
-// and false on failure
-bool
-removeRootPriv(uid_t euid)
-{
- if (seteuid(euid) < 0) {
- Debug("lm", "[removeRootPriv] seteuid failed : %s\n", strerror(errno));
- return false;
- }
-
- Debug("lm", "[removeRootPriv] removed root privileges. Euid is %d\n", euid);
- return true;
-}
-
-// bool restoreRootPriv()
-//
-// - Returns true on success
-// and false on failure
-bool
-restoreRootPriv(uid_t *old_euid)
-{
- if (old_euid)
- *old_euid = geteuid();
- if (seteuid(0) < 0) {
- Debug("lm", "[restoreRootPriv] seteuid root failed : %s\n", strerror(errno));
- return false;
- }
-
- Debug("lm", "[restoreRootPriv] restored root privileges. Euid is %d\n", 0);
-
- return true;
-}
-#endif
/*
* bindProxyPort()
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/mgmt/LocalManager.h
----------------------------------------------------------------------
diff --git a/mgmt/LocalManager.h b/mgmt/LocalManager.h
index 7b677d8..9ea4158 100644
--- a/mgmt/LocalManager.h
+++ b/mgmt/LocalManager.h
@@ -159,11 +159,5 @@ private:
extern LocalManager *lmgmt;
-#if TS_USE_POSIX_CAP
-bool elevateFileAccess(bool);
-#else
-bool restoreRootPriv(uid_t *old_euid = NULL);
-bool removeRootPriv(uid_t euid);
-#endif
#endif /* _LOCAL_MANAGER_H */
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/mgmt/RecordsConfig.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index 4a73f19..647174f 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -1340,6 +1340,9 @@ RecordElement RecordsConfig[] = {
,
{RECT_CONFIG, "proxy.config.plugin.plugin_mgmt_dir", RECD_STRING, TS_BUILD_SYSCONFDIR "/plugins_mgmt", RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
,
+ {RECT_CONFIG, "proxy.config.plugin.load_elevated", RECD_INT, "0", RECU_NULL, RR_NULL, RECC_NULL, "[0-1]", RECA_NULL}
+ ,
+
//##############################################################################
//#
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/mgmt/Rollback.cc
----------------------------------------------------------------------
diff --git a/mgmt/Rollback.cc b/mgmt/Rollback.cc
index e27a745..0399523 100644
--- a/mgmt/Rollback.cc
+++ b/mgmt/Rollback.cc
@@ -29,7 +29,7 @@
#include "MgmtUtils.h"
#include "ExpandingArray.h"
#include "MgmtSocket.h"
-
+#include "ink_cap.h"
#define MAX_VERSION_DIGITS 11
#define DEFAULT_BACKUPS 2
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/proxy/Plugin.cc
----------------------------------------------------------------------
diff --git a/proxy/Plugin.cc b/proxy/Plugin.cc
index 1908199..5b2b19e 100644
--- a/proxy/Plugin.cc
+++ b/proxy/Plugin.cc
@@ -35,6 +35,7 @@
#include "InkAPIInternal.h"
#include "Main.h"
#include "Plugin.h"
+#include "ink_cap.h"
// HPUX:
// LD_SHAREDCMD=ld -b
@@ -136,7 +137,14 @@ plugin_load(int argc, char *argv[])
abort();
}
- init(argc, argv);
+ // elevate the access to read files as root if compiled with capabilities, if not
+ // change the effective user to root
+ {
+ uint32_t elevate_access = 0;
+ REC_ReadConfigInteger(elevate_access, "proxy.config.plugin.load_elevated");
+ ElevateAccess access(elevate_access != 0);
+ init(argc, argv);
+ } // done elevating access
plugin_reg_list.push(plugin_reg_current);
plugin_reg_current = NULL;
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/proxy/http/remap/UrlMapping.cc
----------------------------------------------------------------------
diff --git a/proxy/http/remap/UrlMapping.cc b/proxy/http/remap/UrlMapping.cc
index c96b9b5..d5b00d1 100644
--- a/proxy/http/remap/UrlMapping.cc
+++ b/proxy/http/remap/UrlMapping.cc
@@ -23,7 +23,8 @@
#include "ink_defs.h"
#include "UrlMapping.h"
-
+#include "I_RecCore.h"
+#include "ink_cap.h"
/**
*
**/
@@ -77,8 +78,14 @@ url_mapping::delete_instance(unsigned int index)
void *ih = get_instance(index);
remap_plugin_info* p = get_plugin(index);
- if (ih && p && p->fp_tsremap_delete_instance)
+ if (ih && p && p->fp_tsremap_delete_instance) {
+ // elevate the access to read files as root if compiled with capabilities, if not
+ // change the effective user to root
+ uint32_t elevate_access = 0;
+ REC_ReadConfigInteger(elevate_access, "proxy.config.plugin.load_elevated");
+ ElevateAccess access(elevate_access != 0);
p->fp_tsremap_delete_instance(ih);
+ } // done elevating access
}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/fffb60ed/proxy/http/remap/UrlRewrite.cc
----------------------------------------------------------------------
diff --git a/proxy/http/remap/UrlRewrite.cc b/proxy/http/remap/UrlRewrite.cc
index 8b51897..f88df84 100644
--- a/proxy/http/remap/UrlRewrite.cc
+++ b/proxy/http/remap/UrlRewrite.cc
@@ -34,6 +34,7 @@
#include "UrlMappingPathIndex.h"
#include "ink_string.h"
+#include "ink_cap.h"
unsigned long
@@ -1699,10 +1700,18 @@ UrlRewrite::load_remap_plugin(char *argv[], int argc, url_mapping *mp, char *err
ri.size = sizeof(ri);
ri.tsremap_version = TSREMAP_VERSION;
- if (pi->fp_tsremap_init(&ri, tmpbuf, sizeof(tmpbuf) - 1) != TS_SUCCESS) {
- Warning("Failed to initialize plugin %s (non-zero retval) ... bailing out", pi->path);
- return -5;
- }
+ // elevate the access to read files as root if compiled with capabilities, if not
+ // change the effective user to root
+ {
+ uint32_t elevate_access = 0;
+ REC_ReadConfigInteger(elevate_access, "proxy.config.plugin.load_elevated");
+ ElevateAccess access(elevate_access != 0);
+
+ if (pi->fp_tsremap_init(&ri, tmpbuf, sizeof(tmpbuf) - 1) != TS_SUCCESS) {
+ Warning("Failed to initialize plugin %s (non-zero retval) ... bailing out", pi->path);
+ return -5;
+ }
+ } // done elevating access
Debug("remap_plugin", "Remap plugin \"%s\" - initialization completed", c);
}
@@ -1756,7 +1765,16 @@ UrlRewrite::load_remap_plugin(char *argv[], int argc, url_mapping *mp, char *err
void* ih;
Debug("remap_plugin", "creating new plugin instance");
- TSReturnCode res = pi->fp_tsremap_new_instance(parc, parv, &ih, tmpbuf, sizeof(tmpbuf) - 1);
+
+ TSReturnCode res = TS_ERROR;
+ // elevate the access to read files as root if compiled with capabilities, if not
+ // change the effective user to root
+ {
+ uint32_t elevate_access = 0;
+ REC_ReadConfigInteger(elevate_access, "proxy.config.plugin.load_elevated");
+ ElevateAccess access(elevate_access != 0);
+ res = pi->fp_tsremap_new_instance(parc, parv, &ih, tmpbuf, sizeof(tmpbuf) - 1);
+ } // done elevating access
Debug("remap_plugin", "done creating new plugin instance");