From: Aki Tuomi Date: Mon, 3 Nov 2014 20:08:58 +0000 (+0200) Subject: Throw is serial won't fit into uint32_t, fixes #1009 X-Git-Tag: rec-3.7.0-rc1~173^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=580444077282ca9c53cbca08b3bd8efa58f0336f;p=thirdparty%2Fpdns.git Throw is serial won't fit into uint32_t, fixes #1009 --- diff --git a/pdns/dns.cc b/pdns/dns.cc index 1b0b30984b..d168351921 100644 --- a/pdns/dns.cc +++ b/pdns/dns.cc @@ -197,7 +197,8 @@ void fillSOAData(const string &content, SOAData &data) if(pleft>1) data.hostmaster=attodot(parts[1]); // ahu@ds9a.nl -> ahu.ds9a.nl, piet.puk@ds9a.nl -> piet\.puk.ds9a.nl - data.serial = pleft > 2 ? strtoul(parts[2].c_str(), NULL, 10) : 0; + data.serial = pleft > 2 ? strtoui(parts[2].c_str(), NULL, 10) : 0; + if (data.serial == UINT_MAX && errno == ERANGE) throw PDNSException("serial number too large in '"+parts[2]+"'"); data.refresh = pleft > 3 ? atoi(parts[3].c_str()) : ::arg().asNum("soa-refresh-default"); diff --git a/pdns/misc.cc b/pdns/misc.cc index 5f28dc966e..bc063f66da 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -916,3 +916,14 @@ void setSocketTimestamps(int fd) L< UINT_MAX) { + errno = ERANGE; + return UINT_MAX; + } + + return val; +} diff --git a/pdns/misc.hh b/pdns/misc.hh index ea8906878b..d760f6b9a8 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,8 @@ uint16_t getShort(const unsigned char *p); uint16_t getShort(const char *p); uint32_t getLong(const unsigned char *p); uint32_t getLong(const char *p); +uint32_t strtoui(const char *nptr, char **endptr, int base); + int logFacilityToLOG(unsigned int facility); struct ServiceTuple diff --git a/pdns/rcpgenerator.cc b/pdns/rcpgenerator.cc index 4db2ae6120..a5b04c4e5d 100644 --- a/pdns/rcpgenerator.cc +++ b/pdns/rcpgenerator.cc @@ -62,7 +62,8 @@ void RecordTextReader::xfr32BitInt(uint32_t &val) throw RecordTextException("expected digits at position "+lexical_cast(d_pos)+" in '"+d_string+"'"); char *endptr; - unsigned long ret=strtoul(d_string.c_str() + d_pos, &endptr, 10); + unsigned long ret=strtoui(d_string.c_str() + d_pos, &endptr, 10); + if (ret == UINT_MAX && errno == ERANGE) throw RecordTextException("serial number too large in '"+d_string+"'"); val=ret; d_pos = endptr - d_string.c_str(); diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc index 8f4ed24fe6..37e7612a16 100644 --- a/pdns/test-dnsrecords_cc.cc +++ b/pdns/test-dnsrecords_cc.cc @@ -225,6 +225,7 @@ BOOST_AUTO_TEST_CASE(test_record_types_bad_values) { (case_t(QType::AAAA, "23:00::15::43", zone, false)) // double compression (case_t(QType::AAAA, "2a23:00::15::", zone, false)) // ditto (case_t(QType::AAAA, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff", zone, false)) // truncated wire value + (case_t(QType::SOA, "ns.rec.test hostmaster.test.rec 20130512010 3600 3600 604800 120", zone, false)) // too long serial ; int n=0;