This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 0c5c0935fdad1345aa110252380d56207880b619
Author: Benjamin Mahler <[email protected]>
AuthorDate: Tue Oct 8 23:47:52 2019 -0400

    Added quota config validation for large numbers.
    
    Per MESOS-10008, large scalar values overflow and can crash
    the master. This patch imposes maximums for guarantees and limits
    well below the overflow point, to prevent this from happening.
    
    Review: https://reviews.apache.org/r/71595
---
 src/master/quota.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/src/master/quota.cpp b/src/master/quota.cpp
index 4ecd326..a9ae3aa 100644
--- a/src/master/quota.cpp
+++ b/src/master/quota.cpp
@@ -214,6 +214,63 @@ Option<Error> validate(const QuotaConfig& config)
     return Error("Invalid 'QuotaConfig.role': " + error->message);
   }
 
+  // Before we validate the scalars, we need to check for
+  // our maximum supported quota values. Otherwise, they
+  // will surface as a generic overflow error in the scalar
+  // validation below.
+  //
+  // The underlying fixed precision logic used for
+  // Value::Scalar overflows between:
+  //
+  //   9,223,372,036,854,774 and (ditto) + 1.0
+  //
+  //   double d = 9223372036854774;
+  //   d += 1.0;
+  //   Value::scalar s, zero;
+  //   s.set_value(d);
+  //   s < zero == true; // overflow!
+  //
+  // This works out to ~9 zettabytes (given we use megabytes
+  // as the base unit), we set a limit of 1 exabyte, and we
+  // can increase this later if needed.
+  //
+  // We also impose a limit on cpu, ports and other types of
+  // 1 trillion.
+
+  const int64_t exabyteInMegabytes = 1024ll * 1024ll * 1024ll * 1024ll;
+  const int64_t otherLimit = 1000ll * 1000ll * 1000ll * 1000ll;
+
+  auto validateTooLarge = [&](
+      const Map<string, Value::Scalar>& m) -> Option<Error> {
+    foreach (auto&& pair, m) {
+      if (pair.first == "mem" || pair.first == "disk") {
+        if (pair.second.value() > exabyteInMegabytes) {
+          return Error(
+              "{'" + pair.first + "': " + stringify(pair.second) + "}"
+              " is invalid: values greater than 1 exabyte"
+              " (" + stringify(exabyteInMegabytes) + ") are not supported");
+        }
+      } else if (pair.second.value() > otherLimit) {
+        return Error(
+            "{'" + pair.first + "': " + stringify(pair.second) + "}"
+            " is invalid: values greater than 1 trillion"
+            " (" + stringify(otherLimit) + ") are not supported");
+      }
+    }
+
+    return None();
+  };
+
+  error = validateTooLarge(config.guarantees());
+  if (error.isSome()) {
+    return Error("Invalid 'QuotaConfig.guarantees': " + error->message);
+  }
+
+  error = validateTooLarge(config.limits());
+  if (error.isSome()) {
+    return Error("Invalid 'QuotaConfig.limits': " + error->message);
+  }
+
   // Validate scalar values.
   foreach (auto&& guarantee, config.guarantees()) {
     Option<Error> error =

Reply via email to