]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/fs/rock/RockRebuild.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / fs / rock / RockRebuild.cc
index ff1f9e91bd54dec9f1fd4430f531240b14fa4f2f..4d5790c599255961975644464c153452a677618a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -21,7 +21,9 @@
 #include "Store.h"
 #include "tools.h"
 
+#include <array>
 #include <cerrno>
+#include <cstring>
 
 CBDATA_NAMESPACED_CLASS_INIT(Rock, Rebuild);
 
@@ -507,6 +509,22 @@ Rock::Rebuild::loadOneSlot()
     useNewSlot(slotId, header);
 }
 
+/// whether the given slot buffer is likely to have nothing but zeros, as is
+/// common to slots in pre-initialized (with zeros) db files
+static bool
+ZeroedSlot(const MemBuf &buf)
+{
+    // We could memcmp the entire buffer, but it is probably safe enough to test
+    // a few bytes because even if we do not detect a corrupted entry, it is not
+    // a big deal: Store::UnpackPrefix() rejects all-0s metadata prefix.
+    static const std::array<char, 10> zeros = {};
+
+    if (static_cast<size_t>(buf.contentSize()) < zeros.size())
+        return false; // cannot be sure enough
+
+    return memcmp(buf.content(), zeros.data(), zeros.size()) == 0;
+}
+
 /// parse StoreEntry basics and add them to the map, returning true on success
 bool
 Rock::Rebuild::importEntry(Ipc::StoreMapAnchor &anchor, const sfileno fileno, const DbCellHeader &header)
@@ -515,6 +533,10 @@ Rock::Rebuild::importEntry(Ipc::StoreMapAnchor &anchor, const sfileno fileno, co
     StoreEntry loadedE;
     const uint64_t knownSize = header.entrySize > 0 ?
                                header.entrySize : anchor.basics.swap_file_sz.load();
+
+    if (ZeroedSlot(buf))
+        return false;
+
     if (!storeRebuildParseEntry(buf, loadedE, key, counts, knownSize))
         return false;