From bec5f921a60a2b13056b2e7e6da32578a7ef850a Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sat, 17 Oct 2020 22:50:54 +0000 Subject: [PATCH] Fix buffer overflows in the no_same_sector_overwrites mode --- blockstore_rollback.cpp | 9 +++++++-- blockstore_stable.cpp | 9 +++++++-- blockstore_sync.cpp | 9 +++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/blockstore_rollback.cpp b/blockstore_rollback.cpp index d3003ebb..e0074a66 100644 --- a/blockstore_rollback.cpp +++ b/blockstore_rollback.cpp @@ -89,12 +89,17 @@ int blockstore_impl_t::dequeue_rollback(blockstore_op_t *op) journal.crc32_last = je->crc32; if (cur_sector != journal.cur_sector) { - if (cur_sector == -1) + // Write previous sector. We should write the sector only after filling it, + // because otherwise we'll write a lot more sectors in the "no_same_sector_overwrite" mode + if (cur_sector != -1) + prepare_journal_sector_write(journal, cur_sector, sqe[s++], cb); + else PRIV(op)->min_flushed_journal_sector = 1 + journal.cur_sector; cur_sector = journal.cur_sector; - prepare_journal_sector_write(journal, cur_sector, sqe[s++], cb); } } + if (cur_sector != -1) + prepare_journal_sector_write(journal, cur_sector, sqe[s++], cb); PRIV(op)->max_flushed_journal_sector = 1 + journal.cur_sector; PRIV(op)->pending_ops = s; PRIV(op)->op_state = 1; diff --git a/blockstore_stable.cpp b/blockstore_stable.cpp index 715da837..2d272a65 100644 --- a/blockstore_stable.cpp +++ b/blockstore_stable.cpp @@ -121,12 +121,17 @@ int blockstore_impl_t::dequeue_stable(blockstore_op_t *op) journal.crc32_last = je->crc32; if (cur_sector != journal.cur_sector) { - if (cur_sector == -1) + // Write previous sector. We should write the sector only after filling it, + // because otherwise we'll write a lot more sectors in the "no_same_sector_overwrite" mode + if (cur_sector != -1) + prepare_journal_sector_write(journal, cur_sector, sqe[s++], cb); + else PRIV(op)->min_flushed_journal_sector = 1 + journal.cur_sector; cur_sector = journal.cur_sector; - prepare_journal_sector_write(journal, cur_sector, sqe[s++], cb); } } + if (cur_sector != -1) + prepare_journal_sector_write(journal, cur_sector, sqe[s++], cb); PRIV(op)->max_flushed_journal_sector = 1 + journal.cur_sector; PRIV(op)->pending_ops = s; PRIV(op)->op_state = 1; diff --git a/blockstore_sync.cpp b/blockstore_sync.cpp index 304502ce..e90ddbef 100644 --- a/blockstore_sync.cpp +++ b/blockstore_sync.cpp @@ -154,12 +154,17 @@ int blockstore_impl_t::continue_sync(blockstore_op_t *op) it++; if (cur_sector != journal.cur_sector) { - if (cur_sector == -1) + // Write previous sector. We should write the sector only after filling it, + // because otherwise we'll write a lot more sectors in the "no_same_sector_overwrite" mode + if (cur_sector != -1) + prepare_journal_sector_write(journal, cur_sector, sqe[s++], cb); + else PRIV(op)->min_flushed_journal_sector = 1 + journal.cur_sector; cur_sector = journal.cur_sector; - prepare_journal_sector_write(journal, cur_sector, sqe[s++], cb); } } + if (cur_sector != -1) + prepare_journal_sector_write(journal, cur_sector, sqe[s++], cb); PRIV(op)->max_flushed_journal_sector = 1 + journal.cur_sector; PRIV(op)->pending_ops = s; PRIV(op)->op_state = SYNC_JOURNAL_WRITE_SENT;