You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by gi...@apache.org on 2019/01/28 07:52:39 UTC
[mesos] 08/11: Enabled Seccomp filter in the containerizer launcher.
This is an automated email from the ASF dual-hosted git repository.
gilbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 1eda420ff3fb9c2fc1e9d8840e71812fa1d57ead
Author: Andrei Budnik <ab...@mesosphere.com>
AuthorDate: Sun Jan 27 23:52:03 2019 -0800
Enabled Seccomp filter in the containerizer launcher.
Containerizer launcher creates an instance of `SeccompFilter`, which is
used to setup Seccomp profile using `ContainerSeccompProfile` message
prepared by the `linux/seccomp` isolator.
Review: https://reviews.apache.org/r/68022/
---
src/slave/containerizer/mesos/launch.cpp | 136 +++++++++++++++++++++----------
1 file changed, 95 insertions(+), 41 deletions(-)
diff --git a/src/slave/containerizer/mesos/launch.cpp b/src/slave/containerizer/mesos/launch.cpp
index 2f1c9e7..7f401cd 100644
--- a/src/slave/containerizer/mesos/launch.cpp
+++ b/src/slave/containerizer/mesos/launch.cpp
@@ -65,6 +65,10 @@
#include "linux/ns.hpp"
#endif
+#ifdef ENABLE_SECCOMP_ISOLATOR
+#include "linux/seccomp/seccomp.hpp"
+#endif
+
#ifndef __WINDOWS__
#include "posix/rlimits.hpp"
#endif // __WINDOWS__
@@ -78,12 +82,18 @@ using std::set;
using std::string;
using std::vector;
+using process::Owned;
+
#ifdef __linux__
using mesos::internal::capabilities::Capabilities;
using mesos::internal::capabilities::Capability;
using mesos::internal::capabilities::ProcessCapabilities;
#endif // __linux__
+#ifdef ENABLE_SECCOMP_ISOLATOR
+using mesos::internal::seccomp::SeccompFilter;
+#endif
+
using mesos::slave::ContainerLaunchInfo;
using mesos::slave::ContainerMountInfo;
@@ -485,6 +495,45 @@ static Try<Nothing> enterChroot(const string& rootfs)
}
+#ifdef __linux__
+static void calculateCapabilities(
+ const ContainerLaunchInfo& launchInfo,
+ ProcessCapabilities* capabilities)
+{
+ // If the task has any effective capabilities, grant them to all
+ // the capability sets.
+ if (launchInfo.has_effective_capabilities()) {
+ set<Capability> target =
+ capabilities::convert(launchInfo.effective_capabilities());
+
+ capabilities->set(capabilities::AMBIENT, target);
+ capabilities->set(capabilities::EFFECTIVE, target);
+ capabilities->set(capabilities::PERMITTED, target);
+ capabilities->set(capabilities::INHERITABLE, target);
+ capabilities->set(capabilities::BOUNDING, target);
+ }
+
+ // If we also have bounding capabilities, apply that in preference to
+ // the effective capabilities.
+ if (launchInfo.has_bounding_capabilities()) {
+ set<Capability> bounding =
+ capabilities::convert(launchInfo.bounding_capabilities());
+
+ capabilities->set(capabilities::BOUNDING, bounding);
+ }
+
+ // Force the inherited set to be the same as the bounding set. If we
+ // are root and capabilities have not been specified, then this is a
+ // no-op. If capabilities have been specified, then we need to clip the
+ // inherited set to prevent file-based capabilities granting privileges
+ // outside the bounding set.
+ capabilities->set(
+ capabilities::INHERITABLE,
+ capabilities->get(capabilities::BOUNDING));
+}
+#endif // __linux__
+
+
int MesosContainerizerLaunch::execute()
{
if (flags.help) {
@@ -790,9 +839,10 @@ int MesosContainerizerLaunch::execute()
#ifdef __linux__
// Initialize capabilities support if necessary.
Option<Capabilities> capabilitiesManager = None();
+ const bool needSetCapabilities = launchInfo.has_effective_capabilities() ||
+ launchInfo.has_bounding_capabilities();
- if (launchInfo.has_effective_capabilities() ||
- launchInfo.has_bounding_capabilities()) {
+ if (needSetCapabilities || launchInfo.has_seccomp_profile()) {
Try<Capabilities> _capabilitiesManager = Capabilities::create();
if (_capabilitiesManager.isError()) {
cerr << "Failed to initialize capabilities support: "
@@ -801,15 +851,15 @@ int MesosContainerizerLaunch::execute()
}
capabilitiesManager = _capabilitiesManager.get();
+ }
- // Prevent clearing of capabilities on `setuid`.
- if (uid.isSome()) {
- Try<Nothing> keepCaps = capabilitiesManager->setKeepCaps();
- if (keepCaps.isError()) {
- cerr << "Failed to set process control for keeping capabilities "
- << "on potential uid change: " << keepCaps.error() << endl;
- exitWithStatus(EXIT_FAILURE);
- }
+ // Prevent clearing of capabilities on `setuid`.
+ if (needSetCapabilities && uid.isSome()) {
+ Try<Nothing> keepCaps = capabilitiesManager->setKeepCaps();
+ if (keepCaps.isError()) {
+ cerr << "Failed to set process control for keeping capabilities "
+ << "on potential uid change: " << keepCaps.error() << endl;
+ exitWithStatus(EXIT_FAILURE);
}
}
#else
@@ -892,6 +942,37 @@ int MesosContainerizerLaunch::execute()
}
}
+#ifdef ENABLE_SECCOMP_ISOLATOR
+ if (launchInfo.has_seccomp_profile()) {
+ CHECK_SOME(capabilitiesManager);
+
+ Try<ProcessCapabilities> capabilities = capabilitiesManager->get();
+ if (capabilities.isError()) {
+ cerr << "Failed to get capabilities for the current process: "
+ << capabilities.error() << endl;
+ exitWithStatus(EXIT_FAILURE);
+ }
+
+ calculateCapabilities(launchInfo, &capabilities.get());
+
+ Try<Owned<SeccompFilter>> seccompFilter = SeccompFilter::create(
+ launchInfo.seccomp_profile(),
+ capabilities.get());
+
+ if (seccompFilter.isError()) {
+ cerr << "Failed to create Seccomp filter: "
+ << seccompFilter.error() << endl;
+ exitWithStatus(EXIT_FAILURE);
+ }
+
+ Try<Nothing> load = seccompFilter.get()->load();
+ if (load.isError()) {
+ cerr << "Failed to load Seccomp filter: " << load.error() << endl;
+ exitWithStatus(EXIT_FAILURE);
+ }
+ }
+#endif // ENABLE_SECCOMP_ISOLATOR
+
#ifndef __WINDOWS__
// Change user if provided. Note that we do that after executing the
// preparation commands so that those commands will be run with the
@@ -921,7 +1002,9 @@ int MesosContainerizerLaunch::execute()
#endif // __WINDOWS__
#ifdef __linux__
- if (capabilitiesManager.isSome()) {
+ if (needSetCapabilities) {
+ CHECK_SOME(capabilitiesManager);
+
Try<ProcessCapabilities> capabilities = capabilitiesManager->get();
if (capabilities.isError()) {
cerr << "Failed to get capabilities for the current process: "
@@ -942,36 +1025,7 @@ int MesosContainerizerLaunch::execute()
exitWithStatus(EXIT_FAILURE);
}
- // If the task has any effective capabilities, grant them to all
- // the capability sets.
- if (launchInfo.has_effective_capabilities()) {
- set<Capability> target =
- capabilities::convert(launchInfo.effective_capabilities());
-
- capabilities->set(capabilities::AMBIENT, target);
- capabilities->set(capabilities::EFFECTIVE, target);
- capabilities->set(capabilities::PERMITTED, target);
- capabilities->set(capabilities::INHERITABLE, target);
- capabilities->set(capabilities::BOUNDING, target);
- }
-
- // If we also have bounding capabilities, apply that in preference to
- // the effective capabilities.
- if (launchInfo.has_bounding_capabilities()) {
- set<Capability> bounding =
- capabilities::convert(launchInfo.bounding_capabilities());
-
- capabilities->set(capabilities::BOUNDING, bounding);
- }
-
- // Force the inherited set to be the same as the bounding set. If we
- // are root and capabilities have not been specified, then this is a
- // no-op. If capabilities have been specified, then we need to clip the
- // inherited set to prevent file-based capabilities granting privileges
- // outside the bounding set.
- capabilities->set(
- capabilities::INHERITABLE,
- capabilities->get(capabilities::BOUNDING));
+ calculateCapabilities(launchInfo, &capabilities.get());
Try<Nothing> set = capabilitiesManager->set(capabilities.get());
if (set.isError()) {