Skip to content

Commit

Permalink
fix src/tracer.hxx stack-buffer-overflow when using vsnprintf's retur…
Browse files Browse the repository at this point in the history
…n value (#502) (#503)

* fix src/tracer.hxx stack-buffer-overflow when using vsnprintf's return value (#502)

* 1. add logger_test to code coverage test 2. logger_test set printTestMessage to true   (#502)

---------

Co-authored-by: byronhe <[email protected]>
  • Loading branch information
byronhe and byronhe authored Apr 24, 2024
1 parent 6ca916a commit 17cdd1f
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 18 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ if (CODE_COVERAGE GREATER 0)
timer_test
strfmt_test
stat_mgr_test
logger_test
)

# lcov
Expand Down
38 changes: 20 additions & 18 deletions src/tracer.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,38 @@ limitations under the License.
#include <stdarg.h>

#ifdef _WIN32
static inline std::string msg_if_given
( _Printf_format_string_ const char* format,
... ) {
static inline std::string msg_if_given(_Printf_format_string_ const char* format, ...) {
#else
static inline std::string msg_if_given(const char* format, ...)
__attribute__((format(printf, 1, 2)));


static inline std::string msg_if_given
( const char* format,
... ) {
static inline std::string msg_if_given(const char* format, ...) {
#endif
if (format[0] == 0x0) {
return "";
} else {
_fix_format(format);
size_t len = 0;
char msg[2048];
}
_fix_format(format);
std::string msg(2048, '\0');
for (int i = 0; i < 2; ++i) {
va_list args;
va_start(args, format);
len = vsnprintf(msg, 2048, format, args);
const int len = vsnprintf(&msg[0], msg.size(), format, args);
va_end(args);

// Get rid of newline at the end.
if (msg[len-1] == '\n') {
len--;
msg[len] = 0x0;
if (len < 0) {
return std::string("invalid format ") + format;
}
return std::string(msg, len);
if (static_cast<size_t>(len) < msg.size()) {
msg.resize(len);
break;
}
msg.resize(len + 1);
}

// Get rid of newline at the end.
if ((not msg.empty()) && (msg.back() == '\n')) {
msg.pop_back();
}
return msg;
}

#define L_TRACE (6)
Expand Down
7 changes: 7 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,10 @@ add_dependencies(stat_mgr_test
target_link_libraries(stat_mgr_test
${BUILD_DIR}/${LIBRARY_OUTPUT_NAME})

add_executable(logger_test
unit/logger_test.cxx)
add_dependencies(logger_test
static_lib)
target_link_libraries(logger_test
${BUILD_DIR}/${LIBRARY_OUTPUT_NAME})

111 changes: 111 additions & 0 deletions tests/unit/logger_test.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/************************************************************************
Modifications Copyright 2017-2019 eBay Inc.
Author/Developer(s): Jung-Sang Ahn
Original Copyright:
See URL: https://github.com/datatechnology/cornerstone
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
**************************************************************************/

#include "libnuraft/logger.hxx"
#include "tracer.hxx"

#include "test_common.h"
#include <cstddef>
#include <iostream>
#include <sstream>
#include <string>

using namespace nuraft;

namespace logger_test {

class ToStringStreamLogger : public nuraft::logger {
public:
ToStringStreamLogger() = default;

~ToStringStreamLogger() = default;

void put_details(int level,
const char* source_file,
const char* func_name,
size_t line_number,
const std::string& msg) override {

static const char* const lv_names[7] = {
"====", "FATL", "ERRO", "WARN", "INFO", "DEBG", "TRAC"};

ss << lv_names[level] << " [" << source_file << ":" << line_number << ", "
<< func_name << "]" << msg << "\n";
}

std::string to_str() const { return ss.str(); }

std::stringstream ss;
};

int logger_basic_test() {

ToStringStreamLogger logger;
nuraft::logger* l_ = &logger;
p_db("hello %s", "world");

std::cout << logger.to_str();
return 0;
}

int logger_long_line_test() {

for (int i = 1800; i < 4096; ++i) {
const std::string str(i, 'a');

ToStringStreamLogger logger;
nuraft::logger* l_ = &logger;
p_db("long string: %s", str.c_str());

const std::string log_str = logger.to_str();
CHK_GT(log_str.size(), str.size());
// std::cout << log_str;
}

for (int i = 1; i < 1024; i *= 2) {
const std::string str(1024UL * i, 'a');

ToStringStreamLogger logger;
nuraft::logger* l_ = &logger;
p_db("long string: %s", str.c_str());

const std::string log_str = logger.to_str();
CHK_GT(log_str.size(), str.size());
// std::cout << log_str;
}

return 0;
}

} // namespace logger_test
using namespace logger_test;

int main(int argc, char** argv) {
TestSuite ts(argc, argv);

ts.options.printTestMessage = true;

ts.doTest("logger basic test", logger_basic_test);

ts.doTest("logger long line test", logger_long_line_test);

return 0;
}

0 comments on commit 17cdd1f

Please sign in to comment.