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/02/12 22:22:36 UTC
[mesos] 04/10: Cloned a sealed file of launcher binary.
This is an automated email from the ASF dual-hosted git repository.
gilbert pushed a commit to branch 1.4.x
in repository https://gitbox.apache.org/repos/asf/mesos.git
commit b337b9795a9d38e934259a305d19d9764ec7d124
Author: Gilbert Song <so...@gmail.com>
AuthorDate: Mon Feb 11 12:51:24 2019 -0800
Cloned a sealed file of launcher binary.
Cloned this binary during mesos containerizer create and command
executor launch.
This change would copy the mesos-containerizer binary in memory,
which helps avoid the binary being overwritten.
Review: https://reviews.apache.org/r/69947/
(cherry picked from commit f7407d3d5f0fe7d5c9a06774921de514012a54da)
---
src/launcher/executor.cpp | 23 +++++++++++++++++--
src/slave/containerizer/mesos/containerizer.cpp | 30 +++++++++++++++++++++++--
src/slave/containerizer/mesos/containerizer.hpp | 18 ++++++++++++---
3 files changed, 64 insertions(+), 7 deletions(-)
diff --git a/src/launcher/executor.cpp b/src/launcher/executor.cpp
index b518030..81935eb 100644
--- a/src/launcher/executor.cpp
+++ b/src/launcher/executor.cpp
@@ -76,6 +76,10 @@
#include "internal/devolve.hpp"
#include "internal/evolve.hpp"
+#ifdef __linux__
+#include "linux/memfd.hpp"
+#endif // __linux__
+
#include "logging/logging.hpp"
#include "messages/messages.hpp"
@@ -467,11 +471,26 @@ protected:
launchFlags.launch_info = JSON::protobuf(launchInfo);
+ // Determine the mesos containerizer binary depends on whether we
+ // need to clone and seal it on linux.
+ string initPath = path::join(launcherDir, MESOS_CONTAINERIZER);
+#ifdef __linux__
+ // Clone the launcher binary in memory for security concerns.
+ Try<int_fd> memFd = memfd::cloneSealedFile(initPath);
+ if (memFd.isError()) {
+ ABORT(
+ "Failed to clone a sealed file '" + initPath + "' in memory: " +
+ memFd.error());
+ }
+
+ initPath = "/proc/self/fd/" + stringify(memFd.get());
+#endif // __linux__
+
// TODO(tillt): Consider using a flag allowing / disallowing the
// log output of possibly sensitive data. See MESOS-7292.
string commandString = strings::format(
"%s %s <POSSIBLY-SENSITIVE-DATA>",
- path::join(launcherDir, MESOS_CONTAINERIZER),
+ initPath,
MesosContainerizerLaunch::NAME).get();
LOG(INFO) << "Running '" << commandString << "'";
@@ -487,7 +506,7 @@ protected:
#endif // __WINDOWS__
Try<Subprocess> s = subprocess(
- path::join(launcherDir, MESOS_CONTAINERIZER),
+ initPath,
argv,
Subprocess::FD(STDIN_FILENO),
Subprocess::FD(STDOUT_FILENO),
diff --git a/src/slave/containerizer/mesos/containerizer.cpp b/src/slave/containerizer/mesos/containerizer.cpp
index 3fdd145..1dda19d 100644
--- a/src/slave/containerizer/mesos/containerizer.cpp
+++ b/src/slave/containerizer/mesos/containerizer.cpp
@@ -48,6 +48,10 @@
#include "hook/manager.hpp"
+#ifdef __linux__
+#include "linux/memfd.hpp"
+#endif // __linux__
+
#include "module/manager.hpp"
#include "slave/paths.hpp"
@@ -472,6 +476,23 @@ Try<MesosContainerizer*> MesosContainerizer::create(
_isolators.push_back(Owned<Isolator>(new MesosIsolator(
Owned<MesosIsolatorProcess>(ioSwitchboard.get()))));
+ Option<int_fd> initMemFd;
+
+#ifdef __linux__
+ // Clone the launcher binary in memory for security concerns.
+ Try<int_fd> memFd = memfd::cloneSealedFile(
+ path::join(flags.launcher_dir, MESOS_CONTAINERIZER));
+
+ if (memFd.isError()) {
+ return Error(
+ "Failed to clone a sealed file '" +
+ path::join(flags.launcher_dir, MESOS_CONTAINERIZER) + "' in memory: " +
+ memFd.error());
+ }
+
+ initMemFd = memFd.get();
+#endif // __linux__
+
return new MesosContainerizer(Owned<MesosContainerizerProcess>(
new MesosContainerizerProcess(
flags,
@@ -479,7 +500,8 @@ Try<MesosContainerizer*> MesosContainerizer::create(
ioSwitchboard.get(),
launcher,
provisioner,
- _isolators)));
+ _isolators,
+ initMemFd)));
}
@@ -1746,13 +1768,17 @@ Future<bool> MesosContainerizerProcess::_launch(
launchFlagsEnvironment.end());
// Fork the child using launcher.
+ string initPath = initMemFd.isSome()
+ ? ("/proc/self/fd/" + stringify(initMemFd.get()))
+ : path::join(flags.launcher_dir, MESOS_CONTAINERIZER);
+
vector<string> argv(2);
argv[0] = path::join(flags.launcher_dir, MESOS_CONTAINERIZER);
argv[1] = MesosContainerizerLaunch::NAME;
Try<pid_t> forked = launcher->fork(
containerId,
- argv[0],
+ initPath,
argv,
containerIO.get(),
nullptr,
diff --git a/src/slave/containerizer/mesos/containerizer.hpp b/src/slave/containerizer/mesos/containerizer.hpp
index cc23b4d..7f5066d 100644
--- a/src/slave/containerizer/mesos/containerizer.hpp
+++ b/src/slave/containerizer/mesos/containerizer.hpp
@@ -129,16 +129,27 @@ public:
IOSwitchboard* _ioSwitchboard,
const process::Owned<Launcher>& _launcher,
const process::Shared<Provisioner>& _provisioner,
- const std::vector<process::Owned<mesos::slave::Isolator>>& _isolators)
+ const std::vector<process::Owned<mesos::slave::Isolator>>& _isolators,
+ const Option<int_fd>& _initMemFd)
: ProcessBase(process::ID::generate("mesos-containerizer")),
flags(_flags),
fetcher(_fetcher),
ioSwitchboard(_ioSwitchboard),
launcher(_launcher),
provisioner(_provisioner),
- isolators(_isolators) {}
+ isolators(_isolators),
+ initMemFd(_initMemFd) {}
- virtual ~MesosContainerizerProcess() {}
+ virtual ~MesosContainerizerProcess()
+ {
+ if (initMemFd.isSome()) {
+ Try<Nothing> close = os::close(initMemFd.get());
+ if (close.isError()) {
+ LOG(WARNING) << "Failed to close memfd '" << stringify(initMemFd.get())
+ << "': " << close.error();
+ }
+ }
+ }
virtual process::Future<Nothing> recover(
const Option<state::SlaveState>& state);
@@ -281,6 +292,7 @@ private:
const process::Owned<Launcher> launcher;
const process::Shared<Provisioner> provisioner;
const std::vector<process::Owned<mesos::slave::Isolator>> isolators;
+ const Option<int_fd> initMemFd;
struct Container
{