diff --git a/chrome/utility/safe_browsing/mac/hfs_unittest.cc b/chrome/utility/safe_browsing/mac/hfs_unittest.cc index ba97578118b1c..74810efa5ae0e 100644 --- a/chrome/utility/safe_browsing/mac/hfs_unittest.cc +++ b/chrome/utility/safe_browsing/mac/hfs_unittest.cc @@ -109,6 +109,39 @@ TEST_F(HFSIteratorTest, HFSXCaseSensitive) { TestTargetFiles(&hfs_reader, true); } +// Regression test for the 32-bit node_id * nodeSize overflow in +// HFSBTreeIterator::SeekToNode. The crafted image declares +// firstLeafNode = 0x80001 and nodeSize = 8192; the true byte offset is +// 0x100002000, but uint32_t arithmetic wraps it to 0x2000. The image places a +// decoy leaf containing "decoy.bin" at catalog-fork byte 0x2000. +// +// Vulnerable build: enumerates "/decoy.bin" (wrong-node read). +// Fixed build: seeks to 0x100002000, which lies past the 16 KiB fork; +// iteration yields zero entries. +// +// Generate the input with make_hfs_poc.py and copy it to +// chrome/test/data/safe_browsing/dmg/data/seek_overflow.img +TEST_F(HFSIteratorTest, SeekToNodeInt32Overflow) { + base::File file; + ASSERT_NO_FATAL_FAILURE(test::GetTestFile("seek_overflow.img", &file)); + + FileReadStream stream(file.GetPlatformFile()); + HFSIterator reader(&stream); + ASSERT_TRUE(reader.Open()); + + std::vector entries; + while (reader.Next()) { + entries.push_back(reader.GetPath()); + } + + for (const auto& e : entries) { + LOG(ERROR) << "enumerated: " << e; + } + + // After the fix, the wrapped seek must not land on the decoy leaf. + EXPECT_TRUE(entries.empty()) << "32-bit wrap read decoy node 1 as node 524289"; +} + class HFSFileReadTest : public testing::TestWithParam { protected: void SetUp() override {