Skip to content

Commit 00ffe44

Browse files
authored
utility: fix strftime overflow handling. (istio#4321)
Existing strftime uses did not correctly handle buffer overflow conditions, where strftime returns 0 and the buffer contents are undefined. This was discovered by an internal equivalent of oss-fuzz. Risk level: Low Testing: Unit test and corpus entry added. Signed-off-by: Harvey Tuch <[email protected]>
1 parent af1183c commit 00ffe44

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

source/common/common/utility.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,8 @@ std::string DateFormatter::fromTime(time_t time) const {
167167
gmtime_r(&time, &current_tm);
168168

169169
std::array<char, 1024> buf;
170-
strftime(&buf[0], buf.size(), format_string_.c_str(), &current_tm);
171-
return std::string(&buf[0]);
170+
const size_t len = strftime(&buf[0], buf.size(), format_string_.c_str(), &current_tm);
171+
return std::string(&buf[0], len);
172172
}
173173

174174
std::string
@@ -185,7 +185,7 @@ DateFormatter::fromTimeAndPrepareSpecifierOffsets(time_t time, SpecifierOffsets&
185185
for (const auto& specifier : specifiers_) {
186186
const size_t formatted_length =
187187
strftime(&buf[0], buf.size(), specifier.segment_.c_str(), &current_tm);
188-
absl::StrAppend(&formatted, &buf[0],
188+
absl::StrAppend(&formatted, absl::string_view(&buf[0], formatted_length),
189189
specifier.second_ ? seconds_str : std::string(specifier.width_, '?'));
190190

191191
// This computes and saves offset of each specifier's pattern to correct its position after the

test/common/common/utility_test.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,4 +807,15 @@ TEST(WelfordStandardDeviation, InsufficientData) {
807807
EXPECT_TRUE(std::isnan(wsd.computeStandardDeviation()));
808808
}
809809

810+
TEST(DateFormatter, FromTime) {
811+
const SystemTime time1(std::chrono::seconds(1522796769));
812+
EXPECT_EQ("2018-04-03T23:06:09.000Z", DateFormatter("%Y-%m-%dT%H:%M:%S.000Z").fromTime(time1));
813+
EXPECT_EQ("aaa23", DateFormatter(std::string(3, 'a') + "%H").fromTime(time1));
814+
EXPECT_EQ("", DateFormatter(std::string(1022, 'a') + "%H").fromTime(time1));
815+
const time_t time2 = 0;
816+
EXPECT_EQ("1970-01-01T00:00:00.000Z", DateFormatter("%Y-%m-%dT%H:%M:%S.000Z").fromTime(time2));
817+
EXPECT_EQ("aaa00", DateFormatter(std::string(3, 'a') + "%H").fromTime(time2));
818+
EXPECT_EQ("", DateFormatter(std::string(1022, 'a') + "%H").fromTime(time2));
819+
}
820+
810821
} // namespace Envoy
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
headers_to_add {
2+
header {
3+
key: "foo"
4+
value: "%START_TIME(%0\240&&&&&&&&zzzzzzzzzzzzzamA(24d\240\240\240\240\240\240\240\240Q240\240\240\240\240\020\240^240&&7&&&&&&&&&&\006&val\177\377\376&&aenam\001s %1f, %85/5_inf %8,,,,,,,,,,,,t_timefo 5#5555#555.5, %85/5_inf %8,,,,,,,,,,,,t_t %85555555\2005 %85/5555Fme:\t15227 f-5555_inf 965L5$59f)%"
5+
}
6+
}
7+
headers_to_remove: "7"
8+
request_info {
9+
upstream_metadata {
10+
filter_metadata {
11+
key: ""
12+
value {
13+
}
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)