Repository: mesos
Updated Branches:
  refs/heads/master d8264ec62 -> f480c7f20


stout: Fix bug in IPNetwork::create() with zero prefix.

The previous coding would try to shift a uint32_t value 32 bits to the left; per
C++ spec, this yields undefined behavior. On my machine, this resulted in
treating a prefix of 0 as equivalent to a prefix of 32, which is obviously
wrong.

Spotted via ubsan: see MESOS-3328.

Review: https://reviews.apache.org/r/37903


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f480c7f2
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f480c7f2
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f480c7f2

Branch: refs/heads/master
Commit: f480c7f2032b6ab33a56d1612d23c27caa357e0f
Parents: d8264ec
Author: Neil Conway <[email protected]>
Authored: Mon Sep 28 12:10:56 2015 -0700
Committer: Niklas Q. Nielsen <[email protected]>
Committed: Mon Sep 28 12:10:57 2015 -0700

----------------------------------------------------------------------
 3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp |  7 ++++++-
 3rdparty/libprocess/3rdparty/stout/tests/ip_tests.cpp   | 11 ++++++++---
 2 files changed, 14 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/f480c7f2/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp 
b/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
index 1ad119d..d1e2df6 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp
@@ -396,7 +396,12 @@ inline Try<IPNetwork> IPNetwork::create(const IP& address, 
int prefix)
         return Error("Subnet prefix is larger than 32");
       }
 
-      return IPNetwork(address, IP(0xffffffff << (32 - prefix)));
+      // Avoid left-shifting by 32 bits when prefix is 0.
+      uint32_t mask = 0;
+      if (prefix > 0) {
+        mask = 0xffffffff << (32 - prefix);
+      }
+      return IPNetwork(address, IP(mask));
     }
     default: {
       UNREACHABLE();

http://git-wip-us.apache.org/repos/asf/mesos/blob/f480c7f2/3rdparty/libprocess/3rdparty/stout/tests/ip_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/ip_tests.cpp 
b/3rdparty/libprocess/3rdparty/stout/tests/ip_tests.cpp
index b0cbcb3..cb9cdd2 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/ip_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/ip_tests.cpp
@@ -98,11 +98,16 @@ TEST(NetTest, ConstructIPv4Network)
   EXPECT_ERROR(net::IPNetwork::create(net::IP(0x87654321), net::IP(0xff)));
   EXPECT_ERROR(net::IPNetwork::create(net::IP(0x87654321), net::IP(0xff00ff)));
 
-  EXPECT_SOME(net::IPNetwork::create(net::IP(0x12345678), 16));
-  EXPECT_SOME(net::IPNetwork::create(net::IP(0x12345678), 32));
-  EXPECT_SOME(net::IPNetwork::create(net::IP(0x12345678), 0));
+  Try<net::IPNetwork> n1 = net::IPNetwork::create(net::IP(0x12345678), 16);
+  Try<net::IPNetwork> n2 = net::IPNetwork::create(net::IP(0x12345678), 32);
+  Try<net::IPNetwork> n3 = net::IPNetwork::create(net::IP(0x12345678), 0);
+
+  EXPECT_SOME_EQ(net::IPNetwork::parse("18.52.86.120/16", AF_INET).get(), n1);
+  EXPECT_SOME_EQ(net::IPNetwork::parse("18.52.86.120/32", AF_INET).get(), n2);
+  EXPECT_SOME_EQ(net::IPNetwork::parse("18.52.86.120/0", AF_INET).get(), n3);
 
   EXPECT_ERROR(net::IPNetwork::create(net::IP(0x12345678), 123));
+  EXPECT_ERROR(net::IPNetwork::create(net::IP(0x12345678), -1));
 
   uint32_t address = 0x01020304;
   uint32_t netmask = 0xff000000;

Reply via email to