diff options
author | Casey Bodley <cbodley@users.noreply.github.com> | 2024-12-16 18:13:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-16 18:13:04 +0100 |
commit | 23e184290818537aad5eb694f925ab24f0ab2596 (patch) | |
tree | ea268c8e044028b49809b12953ff6521bc24372b /src/common | |
parent | Merge pull request #60499 from clwluvw/bucket-layout-output (diff) | |
parent | <comomon> fix buffer out-of-bounds in HTMLFormatter (diff) | |
download | ceph-23e184290818537aad5eb694f925ab24f0ab2596.tar.xz ceph-23e184290818537aad5eb694f925ab24f0ab2596.zip |
Merge pull request #60429 from VVoidV/lbr-fix-formatter
<common> fix formatter buffer out-of-bounds
Reviewed-by: Casey Bodley <cbodley@redhat.com>
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/Formatter.cc | 61 | ||||
-rw-r--r-- | src/common/HTMLFormatter.cc | 20 |
2 files changed, 65 insertions, 16 deletions
diff --git a/src/common/Formatter.cc b/src/common/Formatter.cc index fd3b2be0221..cd12e4f9885 100644 --- a/src/common/Formatter.cc +++ b/src/common/Formatter.cc @@ -23,6 +23,8 @@ #include <algorithm> #include <set> #include <limits> +#include <utility> +#include <boost/container/small_vector.hpp> // ----------------------- namespace ceph { @@ -365,10 +367,21 @@ std::ostream& JSONFormatter::dump_stream(std::string_view name) void JSONFormatter::dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) { - char buf[LARGE_SIZE]; - vsnprintf(buf, LARGE_SIZE, fmt, ap); + auto buf = boost::container::small_vector<char, LARGE_SIZE>{ + LARGE_SIZE, boost::container::default_init}; - add_value(name, buf, quoted); + va_list ap_copy; + va_copy(ap_copy, ap); + int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy); + va_end(ap_copy); + + if (std::cmp_greater_equal(len, buf.size())) { + // output was truncated, allocate a buffer large enough + buf.resize(len + 1, boost::container::default_init); + vsnprintf(buf.data(), buf.size(), fmt, ap); + } + + add_value(name, buf.data(), quoted); } int JSONFormatter::get_len() const @@ -550,15 +563,27 @@ std::ostream& XMLFormatter::dump_stream(std::string_view name) void XMLFormatter::dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) { - char buf[LARGE_SIZE]; - size_t len = vsnprintf(buf, LARGE_SIZE, fmt, ap); + auto buf = boost::container::small_vector<char, LARGE_SIZE>{ + LARGE_SIZE, boost::container::default_init}; + + va_list ap_copy; + va_copy(ap_copy, ap); + int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy); + va_end(ap_copy); + + if (std::cmp_greater_equal(len, buf.size())) { + // output was truncated, allocate a buffer large enough + buf.resize(len + 1, boost::container::default_init); + vsnprintf(buf.data(), buf.size(), fmt, ap); + } + auto e = get_xml_name(name); print_spaces(); if (ns) { - m_ss << "<" << e << " xmlns=\"" << ns << "\">" << xml_stream_escaper(std::string_view(buf, len)) << "</" << e << ">"; + m_ss << "<" << e << " xmlns=\"" << ns << "\">" << xml_stream_escaper(std::string_view(buf.data(), len)) << "</" << e << ">"; } else { - m_ss << "<" << e << ">" << xml_stream_escaper(std::string_view(buf, len)) << "</" << e << ">"; + m_ss << "<" << e << ">" << xml_stream_escaper(std::string_view(buf.data(), len)) << "</" << e << ">"; } if (m_pretty) @@ -927,14 +952,26 @@ void TableFormatter::dump_format_va(std::string_view name, const char *fmt, va_list ap) { finish_pending_string(); - char buf[LARGE_SIZE]; - vsnprintf(buf, LARGE_SIZE, fmt, ap); + auto buf = boost::container::small_vector<char, LARGE_SIZE>{ + LARGE_SIZE, boost::container::default_init}; + + va_list ap_copy; + va_copy(ap_copy, ap); + int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy); + va_end(ap_copy); + + if (std::cmp_greater_equal(len, buf.size())) { + // output was truncated, allocate a buffer large enough + buf.resize(len + 1, boost::container::default_init); + vsnprintf(buf.data(), buf.size(), fmt, ap); + } size_t i = m_vec_index(name); if (ns) { - m_ss << ns << "." << buf; - } else - m_ss << buf; + m_ss << ns << "." << buf.data(); + } else { + m_ss << buf.data(); + } m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str())); m_ss.clear(); diff --git a/src/common/HTMLFormatter.cc b/src/common/HTMLFormatter.cc index e7e985531d8..1bc8d864cb6 100644 --- a/src/common/HTMLFormatter.cc +++ b/src/common/HTMLFormatter.cc @@ -23,6 +23,8 @@ #include <stdlib.h> #include <string> #include <string.h> // for strdup +#include <boost/container/small_vector.hpp> +#include <utility> // for std::cmp_greater_equal #include "common/escape.h" @@ -138,17 +140,27 @@ std::ostream& HTMLFormatter::dump_stream(std::string_view name) void HTMLFormatter::dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) { - char buf[LARGE_SIZE]; - size_t len = vsnprintf(buf, LARGE_SIZE, fmt, ap); + auto buf = boost::container::small_vector<char, LARGE_SIZE>{ + LARGE_SIZE, boost::container::default_init}; + + va_list ap_copy; + va_copy(ap_copy, ap); + size_t len = vsnprintf(buf.data(), buf.size(), fmt, ap); + va_end(ap_copy); + + if(std::cmp_greater_equal(len, buf.size())){ + buf.resize(len + 1, boost::container::default_init); + vsnprintf(buf.data(), buf.size(), fmt, ap_copy); + } std::string e(name); print_spaces(); if (ns) { m_ss << "<li xmlns=\"" << ns << "\">" << e << ": " - << xml_stream_escaper(std::string_view(buf, len)) << "</li>"; + << xml_stream_escaper(std::string_view(buf.data(), len)) << "</li>"; } else { m_ss << "<li>" << e << ": " - << xml_stream_escaper(std::string_view(buf, len)) << "</li>"; + << xml_stream_escaper(std::string_view(buf.data(), len)) << "</li>"; } if (m_pretty) |