summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authorCasey Bodley <cbodley@users.noreply.github.com>2024-12-16 18:13:04 +0100
committerGitHub <noreply@github.com>2024-12-16 18:13:04 +0100
commit23e184290818537aad5eb694f925ab24f0ab2596 (patch)
treeea268c8e044028b49809b12953ff6521bc24372b /src/common
parentMerge pull request #60499 from clwluvw/bucket-layout-output (diff)
parent<comomon> fix buffer out-of-bounds in HTMLFormatter (diff)
downloadceph-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.cc61
-rw-r--r--src/common/HTMLFormatter.cc20
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)