From: Michal 'vorner' Vaner Date: Wed, 7 Nov 2012 09:17:31 +0000 (+0100) Subject: [2384] Better TTL range checking X-Git-Tag: trac2487_base~1^2~29^2~2^2~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0c55100a70f0b68afd7880e2b1498f773fbff943;p=thirdparty%2Fkea.git [2384] Better TTL range checking Also check partial values and wrap-arouds for numbers. --- diff --git a/src/lib/dns/rrttl.cc b/src/lib/dns/rrttl.cc index c01b9dae23..e419478ef0 100644 --- a/src/lib/dns/rrttl.cc +++ b/src/lib/dns/rrttl.cc @@ -98,6 +98,17 @@ RRTTL::RRTTL(const std::string& ttlstr) { unit)); // Add what we found val += multiply * value; + // The partial value is still in range (the value can only grow, + // so if we get out now, it won't get better). + // + // Any valid uint32_t number must have at most 10 digits. If it + // has more, it could wrap around the int64_t silently (at least + // in theory, some compilers seem to throw from lexical_cast). + if (unit - pos > 10 || value <= 0 || val <= 0 || + val >= 0xffffffff) { + isc_throw(InvalidRRTTL, "Part of TTL out of range: " << + ttlstr); + } // Move to after the unit (if any). But make sure not to increment // past end, which is, strictly speaking, illegal. pos = unit; diff --git a/src/lib/dns/tests/rrttl_unittest.cc b/src/lib/dns/tests/rrttl_unittest.cc index 4d8939720c..ece9fe8e26 100644 --- a/src/lib/dns/tests/rrttl_unittest.cc +++ b/src/lib/dns/tests/rrttl_unittest.cc @@ -108,6 +108,23 @@ TEST_F(RRTTLTest, fromTextUnit) { // Awkward, but allowed case - the same unit used twice. EXPECT_EQ(20 * 3600, RRTTL("12H8H").getValue()); + // Negative number in part of the expression, but the total is positive. + // Rejected. + EXPECT_THROW(RRTTL("-1S1H"), InvalidRRTTL); + + // Some things out of range in the ttl, but it wraps to number in range + // in int64_t. Should still not get fooled and reject it. + + // First part out of range + EXPECT_THROW(RRTTL("9223372036854775807S9223372036854775807S2S"), + InvalidRRTTL); + // Second part out of range, but it immediately wraps (2S+2^64-2S) + EXPECT_THROW(RRTTL("2S18446744073709551614S"), + InvalidRRTTL); + // The whole thing wraps right away (2^64S) + EXPECT_THROW(RRTTL("18446744073709551616S"), + InvalidRRTTL); + // Missing before unit. EXPECT_THROW(RRTTL("W5H"), InvalidRRTTL); EXPECT_THROW(RRTTL("5hW"), InvalidRRTTL);