From 99c052a34f93d119b75eccdcd489ecd581d48ee9 Mon Sep 17 00:00:00 2001 From: Edouard A Date: Sun, 23 Oct 2016 18:43:29 -0700 Subject: [PATCH] Fix integer overflow in GetL0ThresholdSpeedupCompaction (#1378) --- db/column_family.cc | 30 +++++++++++++++++++++++++----- port/win/io_win.h | 2 +- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/db/column_family.cc b/db/column_family.cc index 2b048576c..2197cb560 100644 --- a/db/column_family.cc +++ b/db/column_family.cc @@ -542,14 +542,34 @@ int GetL0ThresholdSpeedupCompaction(int level0_file_num_compaction_trigger, // SanitizeOptions() ensures it. assert(level0_file_num_compaction_trigger <= level0_slowdown_writes_trigger); + if (level0_file_num_compaction_trigger < 0) { + return std::numeric_limits::max(); + } + + const int twice_level0_trigger = level0_file_num_compaction_trigger * 2; + + // overflow protection + if (twice_level0_trigger < 0) { + return std::numeric_limits::max(); + } + // 1/4 of the way between L0 compaction trigger threshold and slowdown // condition. + const int one_fourth_trigger_slowdown = + level0_file_num_compaction_trigger + + ((level0_slowdown_writes_trigger - level0_file_num_compaction_trigger) / + 4); + + // overflow protection + if (one_fourth_trigger_slowdown < 0) { + return std::numeric_limits::max(); + } + + assert(twice_level0_trigger >= 0); + assert(one_fourth_trigger_slowdown >= 0); + // Or twice as compaction trigger, if it is smaller. - return std::min(level0_file_num_compaction_trigger * 2, - level0_file_num_compaction_trigger + - (level0_slowdown_writes_trigger - - level0_file_num_compaction_trigger) / - 4); + return std::min(twice_level0_trigger, one_fourth_trigger_slowdown); } } // namespace diff --git a/port/win/io_win.h b/port/win/io_win.h index 42846e322..6907aeef1 100644 --- a/port/win/io_win.h +++ b/port/win/io_win.h @@ -26,7 +26,7 @@ namespace port { std::string GetWindowsErrSz(DWORD err); inline Status IOErrorFromWindowsError(const std::string& context, DWORD err) { - return (err == ERROR_HANDLE_DISK_FULL) ? + return ((err == ERROR_HANDLE_DISK_FULL) || (err == ERROR_DISK_FULL)) ? Status::NoSpace(context, GetWindowsErrSz(err)) : Status::IOError(context, GetWindowsErrSz(err)); }