Repository: mesos Updated Branches: refs/heads/master c52f5bf34 -> 362d09592
Improve master robustness against duplicate UPIDs. It is possible for a malicious client to send libprocess SUBSCRIBE requests that will trigger the !frameworks.principals.contains(...) CHECK. This can happen if the client sends a subscribe with a framework ID, then a second subscribe with a different framework ID but the same UPID. The invariant in the master is that a UPID uniquely identifies a given framework. This is violated if we allow multiple frameworks with the same UPID. Review: https://reviews.apache.org/r/58242/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/362d0959 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/362d0959 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/362d0959 Branch: refs/heads/master Commit: 362d0959295bd460fdeb62a7cd80d744c87b84ea Parents: c52f5bf Author: James Peach <[email protected]> Authored: Thu Apr 6 16:46:45 2017 -0700 Committer: Jie Yu <[email protected]> Committed: Thu Apr 6 16:46:45 2017 -0700 ---------------------------------------------------------------------- src/master/master.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/362d0959/src/master/master.cpp ---------------------------------------------------------------------- diff --git a/src/master/master.cpp b/src/master/master.cpp index e547d2c..c1f3c4f 100644 --- a/src/master/master.cpp +++ b/src/master/master.cpp @@ -2912,6 +2912,8 @@ void Master::_subscribe( } } + CHECK(!frameworks.principals.contains(from)); + // Assign a new FrameworkID. FrameworkInfo frameworkInfo_ = frameworkInfo; frameworkInfo_.mutable_id()->CopyFrom(newFrameworkId()); @@ -2931,6 +2933,20 @@ void Master::_subscribe( // If we are here the framework has already been assigned an id. CHECK(!frameworkInfo.id().value().empty()); + // Check whether we got a subscribe from a framework whose UPID duplicates + // a framework that is already connected. Note that we don't send an error + // response because that would go to the framework that is already connected. + if (frameworks.principals.contains(from)) { + foreachvalue (Framework* framework, frameworks.registered) { + if (framework->pid == from && framework->id() != frameworkInfo.id()) { + LOG(ERROR) << "Dropping SUBSCRIBE call for framework '" + << frameworkInfo.name() << "': " << *framework + << " already connected at " << from; + return; + } + } + } + Framework* framework = getFramework(frameworkInfo.id()); if (framework == nullptr) {
