Skip to content

Commit 30ee5b3

Browse files
committed
clamp snprintf result before using it as fwrite length
1 parent c88a9f4 commit 30ee5b3

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

‎3rdparty/minitrace/minitrace.cpp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ void mtr_flush_with_state(int is_last) {
353353
len = snprintf(linebuf, ARRAY_SIZE(linebuf), "%s{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ",\"ph\":\"%c\",\"name\":\"%s\",\"args\":{%s}%s}",
354354
first_line ? "" : ",\n",
355355
cat, raw->pid, raw->tid, raw->ts - time_offset, raw->ph, raw->name, arg_buf, id_buf);
356+
// snprintf returns the length the line would have needed, not what it
357+
// wrote, and a negative value on error, so clamp before using it as a
358+
// write length.
359+
if (len < 0) {
360+
len = 0;
361+
} else if ((size_t)len >= sizeof(linebuf)) {
362+
len = (int)sizeof(linebuf) - 1;
363+
}
356364
fwrite(linebuf, 1, len, f);
357365
first_line = 0;
358366

‎tests/gtest_loggers.cpp‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,33 @@ TEST_F(LoggerTest, MinitraceLogger_TransitionTypes)
261261
ASSERT_TRUE(std::filesystem::exists(filepath));
262262
}
263263

264+
TEST_F(LoggerTest, MinitraceLogger_LongNodeName)
265+
{
266+
// The node name goes into a 1024 byte line buffer. A name long enough to
267+
// overflow it used to be written out with snprintf's would-be length, which
268+
// reads past the buffer and copies stack bytes into the trace file.
269+
const std::string long_name(1000, 'A');
270+
const std::string xml_text = R"(
271+
<root BTCPP_format="4">
272+
<BehaviorTree>
273+
<AlwaysSuccess name=")" +
274+
long_name + R"("/>
275+
</BehaviorTree>
276+
</root>)";
277+
278+
auto tree = factory.createTreeFromText(xml_text);
279+
std::string filepath = test_dir + "/trace_long_name.json";
280+
281+
{
282+
MinitraceLogger logger(tree, filepath.c_str());
283+
tree.tickWhileRunning();
284+
logger.flush();
285+
}
286+
287+
ASSERT_TRUE(std::filesystem::exists(filepath));
288+
ASSERT_LT(std::filesystem::file_size(filepath), 4096u);
289+
}
290+
264291
// ============ SqliteLogger tests ============
265292

266293
TEST_F(LoggerTest, SqliteLogger_Creation_db3)

0 commit comments

Comments
 (0)