Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(937)

Side by Side Diff: chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc

Issue 10093004: Double-check safe-browsing database validity on update failure. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Check size before reading. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/safe_browsing/safe_browsing_store_file.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h" 5 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/md5.h"
8 #include "base/scoped_temp_dir.h" 9 #include "base/scoped_temp_dir.h"
9 #include "chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.h" 10 #include "chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.h"
10 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/gtest/include/gtest/gtest.h"
11 #include "testing/platform_test.h" 12 #include "testing/platform_test.h"
12 13
13 namespace { 14 namespace {
14 15
15 const FilePath::CharType kFolderPrefix[] = 16 const FilePath::CharType kFolderPrefix[] =
16 FILE_PATH_LITERAL("SafeBrowsingTestStoreFile"); 17 FILE_PATH_LITERAL("SafeBrowsingTestStoreFile");
17 18
18 class SafeBrowsingStoreFileTest : public PlatformTest { 19 class SafeBrowsingStoreFileTest : public PlatformTest {
19 public: 20 public:
20 virtual void SetUp() { 21 virtual void SetUp() {
21 PlatformTest::SetUp(); 22 PlatformTest::SetUp();
22 23
23 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 24 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
24 25
25 filename_ = temp_dir_.path(); 26 filename_ = temp_dir_.path();
26 filename_ = filename_.AppendASCII("SafeBrowsingTestStore"); 27 filename_ = filename_.AppendASCII("SafeBrowsingTestStore");
27 28
28 store_.reset(new SafeBrowsingStoreFile()); 29 store_.reset(new SafeBrowsingStoreFile());
29 store_->Init(filename_, base::Closure()); 30 store_->Init(filename_,
31 base::Bind(&SafeBrowsingStoreFileTest::OnCorruptionDetected,
32 base::Unretained(this)));
33 corruption_detected_ = false;
30 } 34 }
31 virtual void TearDown() { 35 virtual void TearDown() {
32 if (store_.get()) 36 if (store_.get())
33 store_->Delete(); 37 store_->Delete();
34 store_.reset(); 38 store_.reset();
35 39
36 PlatformTest::TearDown(); 40 PlatformTest::TearDown();
37 } 41 }
38 42
39 void OnCorruptionDetected() { 43 void OnCorruptionDetected() {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 EXPECT_TRUE(store_->Delete()); 75 EXPECT_TRUE(store_->Delete());
72 EXPECT_FALSE(file_util::PathExists(filename_)); 76 EXPECT_FALSE(file_util::PathExists(filename_));
73 EXPECT_FALSE(file_util::PathExists(temp_file)); 77 EXPECT_FALSE(file_util::PathExists(temp_file));
74 } 78 }
75 79
76 // Test basic corruption-handling. 80 // Test basic corruption-handling.
77 TEST_F(SafeBrowsingStoreFileTest, DetectsCorruption) { 81 TEST_F(SafeBrowsingStoreFileTest, DetectsCorruption) {
78 // Load a store with some data. 82 // Load a store with some data.
79 SafeBrowsingStoreTestStorePrefix(store_.get()); 83 SafeBrowsingStoreTestStorePrefix(store_.get());
80 84
81 SafeBrowsingStoreFile test_store;
82 test_store.Init(
83 filename_,
84 base::Bind(&SafeBrowsingStoreFileTest::OnCorruptionDetected,
85 base::Unretained(this)));
86
87 corruption_detected_ = false;
88
89 // Can successfully open and read the store. 85 // Can successfully open and read the store.
90 std::vector<SBAddFullHash> pending_adds; 86 std::vector<SBAddFullHash> pending_adds;
91 std::set<SBPrefix> prefix_misses; 87 std::set<SBPrefix> prefix_misses;
92 SBAddPrefixes orig_prefixes; 88 SBAddPrefixes orig_prefixes;
93 std::vector<SBAddFullHash> orig_hashes; 89 std::vector<SBAddFullHash> orig_hashes;
94 EXPECT_TRUE(test_store.BeginUpdate()); 90 EXPECT_TRUE(store_->BeginUpdate());
95 EXPECT_TRUE(test_store.FinishUpdate(pending_adds, prefix_misses, 91 EXPECT_TRUE(store_->FinishUpdate(pending_adds, prefix_misses,
96 &orig_prefixes, &orig_hashes)); 92 &orig_prefixes, &orig_hashes));
97 EXPECT_GT(orig_prefixes.size(), 0U); 93 EXPECT_GT(orig_prefixes.size(), 0U);
98 EXPECT_GT(orig_hashes.size(), 0U); 94 EXPECT_GT(orig_hashes.size(), 0U);
99 EXPECT_FALSE(corruption_detected_); 95 EXPECT_FALSE(corruption_detected_);
100 96
101 // Corrupt the store. 97 // Corrupt the store.
102 file_util::ScopedFILE file(file_util::OpenFile(filename_, "rb+")); 98 file_util::ScopedFILE file(file_util::OpenFile(filename_, "rb+"));
103 const long kOffset = 60; 99 const long kOffset = 60;
104 EXPECT_EQ(fseek(file.get(), kOffset, SEEK_SET), 0); 100 EXPECT_EQ(fseek(file.get(), kOffset, SEEK_SET), 0);
105 const int32 kZero = 0; 101 const int32 kZero = 0;
106 int32 previous = kZero; 102 int32 previous = kZero;
107 EXPECT_EQ(fread(&previous, sizeof(previous), 1, file.get()), 1U); 103 EXPECT_EQ(fread(&previous, sizeof(previous), 1, file.get()), 1U);
108 EXPECT_NE(previous, kZero); 104 EXPECT_NE(previous, kZero);
109 EXPECT_EQ(fseek(file.get(), kOffset, SEEK_SET), 0); 105 EXPECT_EQ(fseek(file.get(), kOffset, SEEK_SET), 0);
110 EXPECT_EQ(fwrite(&kZero, sizeof(kZero), 1, file.get()), 1U); 106 EXPECT_EQ(fwrite(&kZero, sizeof(kZero), 1, file.get()), 1U);
111 file.reset(); 107 file.reset();
112 108
113 // Update fails and corruption callback is called. 109 // Update fails and corruption callback is called.
114 SBAddPrefixes add_prefixes; 110 SBAddPrefixes add_prefixes;
115 std::vector<SBAddFullHash> add_hashes; 111 std::vector<SBAddFullHash> add_hashes;
116 corruption_detected_ = false; 112 corruption_detected_ = false;
117 EXPECT_TRUE(test_store.BeginUpdate()); 113 EXPECT_TRUE(store_->BeginUpdate());
118 EXPECT_FALSE(test_store.FinishUpdate(pending_adds, prefix_misses, 114 EXPECT_FALSE(store_->FinishUpdate(pending_adds, prefix_misses,
119 &add_prefixes, &add_hashes)); 115 &add_prefixes, &add_hashes));
120 EXPECT_TRUE(corruption_detected_); 116 EXPECT_TRUE(corruption_detected_);
121 EXPECT_EQ(add_prefixes.size(), 0U); 117 EXPECT_EQ(add_prefixes.size(), 0U);
122 EXPECT_EQ(add_hashes.size(), 0U); 118 EXPECT_EQ(add_hashes.size(), 0U);
123 119
124 // Make it look like there is a lot of add-chunks-seen data. 120 // Make it look like there is a lot of add-chunks-seen data.
125 const long kAddChunkCountOffset = 2 * sizeof(int32); 121 const long kAddChunkCountOffset = 2 * sizeof(int32);
126 const int32 kLargeCount = 1000 * 1000 * 1000; 122 const int32 kLargeCount = 1000 * 1000 * 1000;
127 file.reset(file_util::OpenFile(filename_, "rb+")); 123 file.reset(file_util::OpenFile(filename_, "rb+"));
128 EXPECT_EQ(fseek(file.get(), kAddChunkCountOffset, SEEK_SET), 0); 124 EXPECT_EQ(fseek(file.get(), kAddChunkCountOffset, SEEK_SET), 0);
129 EXPECT_EQ(fwrite(&kLargeCount, sizeof(kLargeCount), 1, file.get()), 1U); 125 EXPECT_EQ(fwrite(&kLargeCount, sizeof(kLargeCount), 1, file.get()), 1U);
130 file.reset(); 126 file.reset();
131 127
132 // Detects corruption and fails to even begin the update. 128 // Detects corruption and fails to even begin the update.
133 corruption_detected_ = false; 129 corruption_detected_ = false;
134 EXPECT_FALSE(test_store.BeginUpdate()); 130 EXPECT_FALSE(store_->BeginUpdate());
135 EXPECT_TRUE(corruption_detected_); 131 EXPECT_TRUE(corruption_detected_);
136 } 132 }
137 133
134 TEST_F(SafeBrowsingStoreFileTest, CheckValidity) {
135 // Empty store is valid.
136 EXPECT_FALSE(file_util::PathExists(filename_));
137 ASSERT_TRUE(store_->BeginUpdate());
138 EXPECT_FALSE(corruption_detected_);
139 EXPECT_TRUE(store_->CheckValidity());
140 EXPECT_FALSE(corruption_detected_);
141 EXPECT_TRUE(store_->CancelUpdate());
142
143 // A store with some data is valid.
144 EXPECT_FALSE(file_util::PathExists(filename_));
145 SafeBrowsingStoreTestStorePrefix(store_.get());
146 EXPECT_TRUE(file_util::PathExists(filename_));
147 ASSERT_TRUE(store_->BeginUpdate());
148 EXPECT_FALSE(corruption_detected_);
149 EXPECT_TRUE(store_->CheckValidity());
150 EXPECT_FALSE(corruption_detected_);
151 EXPECT_TRUE(store_->CancelUpdate());
152 }
153
154 // Corrupt the payload.
155 TEST_F(SafeBrowsingStoreFileTest, CheckValidityPayload) {
156 SafeBrowsingStoreTestStorePrefix(store_.get());
157 EXPECT_TRUE(file_util::PathExists(filename_));
158
159 // 37 is the most random prime number. It's also past the header,
160 // as corrupting the header would fail BeginUpdate() in which case
161 // CheckValidity() cannot be called.
162 const size_t kOffset = 37;
163
164 {
165 file_util::ScopedFILE file(file_util::OpenFile(filename_, "rb+"));
166 EXPECT_EQ(0, fseek(file.get(), kOffset, SEEK_SET));
167 EXPECT_GE(fputs("hello", file.get()), 0);
168 }
169 ASSERT_TRUE(store_->BeginUpdate());
170 EXPECT_FALSE(corruption_detected_);
171 EXPECT_FALSE(store_->CheckValidity());
172 EXPECT_TRUE(corruption_detected_);
173 EXPECT_TRUE(store_->CancelUpdate());
174 }
175
176 // Corrupt the checksum.
177 TEST_F(SafeBrowsingStoreFileTest, CheckValidityChecksum) {
178 SafeBrowsingStoreTestStorePrefix(store_.get());
179 EXPECT_TRUE(file_util::PathExists(filename_));
180
181 // An offset from the end of the file which is in the checksum.
182 const int kOffset = -static_cast<int>(sizeof(base::MD5Digest));
183
184 {
185 file_util::ScopedFILE file(file_util::OpenFile(filename_, "rb+"));
186 EXPECT_EQ(0, fseek(file.get(), kOffset, SEEK_END));
187 EXPECT_GE(fputs("hello", file.get()), 0);
188 }
189 ASSERT_TRUE(store_->BeginUpdate());
190 EXPECT_FALSE(corruption_detected_);
191 EXPECT_FALSE(store_->CheckValidity());
192 EXPECT_TRUE(corruption_detected_);
193 EXPECT_TRUE(store_->CancelUpdate());
194 }
195
138 } // namespace 196 } // namespace
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/safe_browsing_store_file.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698