Commitlog replayer: Range-check skip call

Fixes #15269

If segment being replayed is corrupted/truncated we can attempt skipping
completely bogues byte amounts, which can cause assert (i.e. crash) in
file_data_source_impl. This is not a crash-level error, so ensure we
range check the distance in the reader.

v2: Add to corrupt_size if trying to skip more than available. The amount added is "wrong", but at least will
    ensure we log the fact that things are broken

Closes scylladb/scylladb#15270

(cherry picked from commit 6ffb482bf3)
This commit is contained in:
Calle Wilund
2023-09-04 12:59:34 +00:00
committed by Botond Dénes
parent f126ccb2e9
commit e3153dd5b0

View File

@@ -2628,12 +2628,20 @@ db::commitlog::read_log_file(sstring filename, sstring pfx, commit_load_reader_f
return eof || next == pos;
}
future<> skip(size_t bytes) {
pos += bytes;
if (pos > file_size) {
auto n = std::min(file_size - pos, bytes);
pos += n;
if (pos == file_size) {
eof = true;
pos = file_size;
}
return fin.skip(bytes);
if (n < bytes) {
// if we are trying to skip past end, we have at least
// the bytes skipped or the source from where we read
// this corrupt. So add at least four bytes. This is
// inexact, but adding the full "bytes" is equally wrong
// since it could be complete garbled junk.
corrupt_size += std::max(n, sizeof(uint32_t));
}
return fin.skip(n);
}
void stop() {
eof = true;