Skip to content

Commit da3ccdf

Browse files
committed
osd: Fix segfault in EC debug string
The old debug_string implementation was potentially reading up to 3 bytes off the end of an array. It was also doing lots of unnecessary bufferlist reconstructs. This refactor of this function fixes both issues. Signed-off-by: Alex Ainscow <[email protected]>
1 parent acca514 commit da3ccdf

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

src/osd/ECUtil.cc

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -987,25 +987,47 @@ bufferlist shard_extent_map_t::get_ro_buffer() const {
987987
return get_ro_buffer(ro_start, ro_end - ro_start);
988988
}
989989

990+
bool get_int_from_bufferlist(bufferlist bl, int offset, uint32_t *value) {
991+
*value = 0;
992+
993+
if (bl.length() < offset + sizeof(uint32_t)) {
994+
return false;
995+
}
996+
997+
auto bl_iter = bl.begin();
998+
bl_iter += offset;
999+
unsigned b = 0;
1000+
for (; b < sizeof(uint32_t); ++b, ++bl_iter) {
1001+
ceph_assert(bl_iter != bl.end());
1002+
*value |= (((unsigned int)bl_iter.get_current_ptr().c_str()[0]) << b);
1003+
}
1004+
return true;
1005+
}
1006+
9901007
std::string shard_extent_map_t::debug_string(uint64_t interval, uint64_t offset) const {
9911008
std::stringstream str;
9921009
str << "shard_extent_map_t: " << *this << " bufs: [";
9931010

9941011
bool s_comma = false;
9951012
for (auto &&[shard, emap] : get_extent_maps()) {
996-
if (s_comma) str << ", ";
1013+
if (s_comma) {
1014+
str << ", ";
1015+
}
9971016
s_comma = true;
9981017
str << shard << ": [";
9991018

10001019
bool comma = false;
10011020
for (auto &&extent : emap) {
10021021
bufferlist bl = extent.get_val();
1003-
char *buf = bl.c_str();
1004-
for (uint64_t i = 0; i < extent.get_len(); i += interval) {
1005-
int *seed = (int*)&buf[i + offset];
1006-
if (comma) str << ", ";
1007-
str << (i + extent.get_off()) << ":" << std::to_string(*seed);
1022+
uint32_t seed;
1023+
int i = 0;
1024+
while (get_int_from_bufferlist(bl, i + offset, &seed)) {
1025+
if (comma) {
1026+
str << ", ";
1027+
}
1028+
str << (i + extent.get_off()) << ":" << seed;
10081029
comma = true;
1030+
i += interval;
10091031
}
10101032
}
10111033
str << "]";

src/test/osd/TestECBackend.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,9 @@ class ErasureCodeDummyImpl : public ErasureCodeInterface {
297297
};
298298

299299
class ECListenerStub : public ECListener {
300+
301+
302+
private:
300303
OSDMapRef osd_map_ref;
301304
pg_info_t pg_info;
302305
set<pg_shard_t> backfill_shards;

src/test/osd/TestECUtil.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,4 +1080,24 @@ TEST(ECUtil, insert_parity_buffer_into_sem) {
10801080
ASSERT_EQ(4096, sem.ro_start);
10811081
ASSERT_EQ(8192, sem.ro_end);
10821082
}
1083+
}
1084+
1085+
// Debug String test, to track down seg-fault found by teuthology.
1086+
TEST(ECUtil, debug_string)
1087+
{
1088+
int k=3;
1089+
int m=2;
1090+
int chunk_size = 4096;
1091+
1092+
stripe_info_t sinfo(k, m, chunk_size*k, vector<shard_id_t>(0));
1093+
shard_extent_map_t semap(&sinfo);
1094+
1095+
bufferlist bl0, bl1;
1096+
bl0.append_zero(750);
1097+
bl1.append_zero(3516);
1098+
1099+
semap.insert_in_shard(shard_id_t(0), 352256, bl0);
1100+
semap.insert_in_shard(shard_id_t(0), 348740, bl1);
1101+
1102+
semap.debug_string(2048, 0);
10831103
}

0 commit comments

Comments
 (0)