From: Otto Moerbeek Date: Wed, 4 Feb 2026 10:51:35 +0000 (+0100) Subject: More (allocation) error checking fix a type X-Git-Tag: rec-5.5.0-alpha0~30^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1716537236b34e981de491fe39f6005ba5db3c02;p=thirdparty%2Fpdns.git More (allocation) error checking fix a type Signed-off-by: Otto Moerbeek --- diff --git a/pdns/base64.cc b/pdns/base64.cc index 0609385797..5eb10a70c1 100644 --- a/pdns/base64.cc +++ b/pdns/base64.cc @@ -19,31 +19,44 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifdef HAVE_CONFIG_H + #include "config.h" -#endif + #include "base64.hh" #include #include #include #include -template int B64Decode(const std::string& src, Container& dst) + +template int B64Decode(const std::string& src, Container& dst) { if (src.empty() ) { dst.clear(); return 0; } - int dlen = ( src.length() * 6 + 7 ) / 8 ; - ssize_t olen = 0; + // check if the dlen computation might overflow or it does not fit into an int (for IO_write) + if (src.length() > std::numeric_limits::max() / 7 || src.length() > std::numeric_limits::max()) { + throw std::runtime_error("B64Decode too large"); + } + const size_t dlen = (src.length() * 6 + 7) / 8 ; dst.resize(dlen); - BIO *bio, *b64; - bio = BIO_new(BIO_s_mem()); - BIO_write(bio, src.c_str(), src.length()); - b64 = BIO_new(BIO_f_base64()); + BIO* bio = BIO_new(BIO_s_mem()); + if (bio == nullptr) { + throw std::runtime_error("BIO_new failed"); + } + if (BIO_write(bio, src.c_str(), src.length()) != static_cast(src.length())) { + BIO_free_all(bio); + throw std::runtime_error("BIO_write failed"); + } + BIO* b64 = BIO_new(BIO_f_base64()); + if (b64 == nullptr) { + BIO_free_all(bio); + throw std::runtime_error("BIO_new failed"); + } bio = BIO_push(b64, bio); BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); - olen = BIO_read(b64, &dst.at(0), dlen); + ssize_t olen = BIO_read(b64, &dst.at(0), dlen); if ((olen == 0 || olen == -1) && BIO_should_retry(bio)) { BIO_free_all(bio); throw std::runtime_error("BIO_read failed to read all data from memory buffer"); @@ -61,10 +74,15 @@ template int B64Decode(const std::string& strInput, std::string& st std::string Base64Encode(const std::string& src) { if (!src.empty()) { - size_t olen = 0; - BIO *bio, *b64; - b64 = BIO_new(BIO_f_base64()); - bio = BIO_new(BIO_s_mem()); + BIO* b64 = BIO_new(BIO_f_base64()); + if (b64 == nullptr) { + throw std::runtime_error("BIO_new failed"); + } + BIO* bio = BIO_new(BIO_s_mem()); + if (bio == nullptr) { + BIO_free_all(b64); + std::runtime_error("BIO_new failed"); + } bio = BIO_push(b64, bio); BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); int bioWriteRet = BIO_write(bio, src.c_str(), src.length()); @@ -75,7 +93,7 @@ std::string Base64Encode(const std::string& src) (void)BIO_flush(bio); char* pp; std::string out; - olen = BIO_get_mem_data(bio, &pp); + size_t olen = BIO_get_mem_data(bio, &pp); if (olen > 0) { out = std::string(pp, olen); } diff --git a/pdns/base64.hh b/pdns/base64.hh index f07814bf1b..eaf3e0a070 100644 --- a/pdns/base64.hh +++ b/pdns/base64.hh @@ -22,5 +22,5 @@ #pragma once #include -template int B64Decode(const std::string& strInput, Container& strOutput); -std::string Base64Encode (const std::string& src); +template int B64Decode(const std::string& strInput, Container& strOutput); +std::string Base64Encode(const std::string& src);