• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "update_engine/payload_consumer/delta_performer.h"
18 
19 #include <inttypes.h>
20 #include <sys/mount.h>
21 
22 #include <algorithm>
23 #include <string>
24 #include <vector>
25 
26 #include <base/files/file_path.h>
27 #include <base/files/file_util.h>
28 #include <base/strings/string_util.h>
29 #include <base/strings/stringprintf.h>
30 #include <google/protobuf/repeated_field.h>
31 #include <gtest/gtest.h>
32 
33 #include "update_engine/common/constants.h"
34 #include "update_engine/common/fake_boot_control.h"
35 #include "update_engine/common/fake_hardware.h"
36 #include "update_engine/common/mock_prefs.h"
37 #include "update_engine/common/test_utils.h"
38 #include "update_engine/common/utils.h"
39 #include "update_engine/payload_consumer/mock_download_action.h"
40 #include "update_engine/payload_consumer/payload_constants.h"
41 #include "update_engine/payload_consumer/payload_verifier.h"
42 #include "update_engine/payload_generator/delta_diff_generator.h"
43 #include "update_engine/payload_generator/payload_signer.h"
44 #include "update_engine/update_metadata.pb.h"
45 
46 namespace chromeos_update_engine {
47 
48 using std::string;
49 using std::vector;
50 using test_utils::ScopedLoopMounter;
51 using test_utils::System;
52 using test_utils::kRandomString;
53 using testing::Return;
54 using testing::_;
55 
56 extern const char* kUnittestPrivateKeyPath;
57 extern const char* kUnittestPublicKeyPath;
58 extern const char* kUnittestPrivateKey2Path;
59 extern const char* kUnittestPublicKey2Path;
60 
61 static const uint32_t kDefaultKernelSize = 4096;  // Something small for a test
62 static const uint8_t kNewData[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
63                                    'n', 'e', 'w', ' ', 'd', 'a', 't', 'a', '.'};
64 
65 namespace {
66 struct DeltaState {
67   string a_img;
68   string b_img;
69   string result_img;
70   size_t image_size;
71 
72   string delta_path;
73   uint64_t metadata_size;
74 
75   string old_kernel;
76   brillo::Blob old_kernel_data;
77 
78   string new_kernel;
79   brillo::Blob new_kernel_data;
80 
81   string result_kernel;
82   brillo::Blob result_kernel_data;
83   size_t kernel_size;
84 
85   // The InstallPlan referenced by the DeltaPerformer. This needs to outlive
86   // the DeltaPerformer.
87   InstallPlan install_plan;
88 
89   // The in-memory copy of delta file.
90   brillo::Blob delta;
91 
92   // Mock and fake instances used by the delta performer.
93   FakeBootControl fake_boot_control_;
94   FakeHardware fake_hardware_;
95   MockDownloadActionDelegate mock_delegate_;
96 };
97 
98 enum SignatureTest {
99   kSignatureNone,  // No payload signing.
100   kSignatureGenerator,  // Sign the payload at generation time.
101   kSignatureGenerated,  // Sign the payload after it's generated.
102   kSignatureGeneratedPlaceholder,  // Insert placeholder signatures, then real.
103   kSignatureGeneratedPlaceholderMismatch,  // Insert a wrong sized placeholder.
104   kSignatureGeneratedShell,  // Sign the generated payload through shell cmds.
105   kSignatureGeneratedShellBadKey,  // Sign with a bad key through shell cmds.
106   kSignatureGeneratedShellRotateCl1,  // Rotate key, test client v1
107   kSignatureGeneratedShellRotateCl2,  // Rotate key, test client v2
108 };
109 
110 enum OperationHashTest {
111   kInvalidOperationData,
112   kValidOperationData,
113 };
114 
115 }  // namespace
116 
117 class DeltaPerformerIntegrationTest : public ::testing::Test {
118  public:
SetSupportedVersion(DeltaPerformer * performer,uint64_t minor_version)119   static void SetSupportedVersion(DeltaPerformer* performer,
120                                   uint64_t minor_version) {
121     performer->supported_minor_version_ = minor_version;
122   }
123 };
124 
CompareFilesByBlock(const string & a_file,const string & b_file,size_t image_size)125 static void CompareFilesByBlock(const string& a_file, const string& b_file,
126                                 size_t image_size) {
127   EXPECT_EQ(0U, image_size % kBlockSize);
128 
129   brillo::Blob a_data, b_data;
130   EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
131   EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
132 
133   EXPECT_GE(a_data.size(), image_size);
134   EXPECT_GE(b_data.size(), image_size);
135   for (size_t i = 0; i < image_size; i += kBlockSize) {
136     EXPECT_EQ(0U, i % kBlockSize);
137     brillo::Blob a_sub(&a_data[i], &a_data[i + kBlockSize]);
138     brillo::Blob b_sub(&b_data[i], &b_data[i + kBlockSize]);
139     EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
140   }
141   if (::testing::Test::HasNonfatalFailure()) {
142     LOG(INFO) << "Compared filesystems with size " << image_size
143               << ", partition A " << a_file << " size: " << a_data.size()
144               << ", partition B " << b_file << " size: " << b_data.size();
145   }
146 }
147 
WriteSparseFile(const string & path,off_t size)148 static bool WriteSparseFile(const string& path, off_t size) {
149   int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
150   TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
151   ScopedFdCloser fd_closer(&fd);
152   off_t rc = lseek(fd, size + 1, SEEK_SET);
153   TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1));
154   int return_code = ftruncate(fd, size);
155   TEST_AND_RETURN_FALSE_ERRNO(return_code == 0);
156   return true;
157 }
158 
GetSignatureSize(const string & private_key_path)159 static size_t GetSignatureSize(const string& private_key_path) {
160   const brillo::Blob data(1, 'x');
161   brillo::Blob hash;
162   EXPECT_TRUE(HashCalculator::RawHashOfData(data, &hash));
163   brillo::Blob signature;
164   EXPECT_TRUE(PayloadSigner::SignHash(hash,
165                                       private_key_path,
166                                       &signature));
167   return signature.size();
168 }
169 
InsertSignaturePlaceholder(int signature_size,const string & payload_path,uint64_t * out_metadata_size)170 static bool InsertSignaturePlaceholder(int signature_size,
171                                        const string& payload_path,
172                                        uint64_t* out_metadata_size) {
173   vector<brillo::Blob> signatures;
174   signatures.push_back(brillo::Blob(signature_size, 0));
175 
176   return PayloadSigner::AddSignatureToPayload(
177       payload_path,
178       signatures,
179       {},
180       payload_path,
181       out_metadata_size);
182 }
183 
SignGeneratedPayload(const string & payload_path,uint64_t * out_metadata_size)184 static void SignGeneratedPayload(const string& payload_path,
185                                  uint64_t* out_metadata_size) {
186   int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
187   brillo::Blob hash;
188   ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
189       payload_path,
190       vector<int>(1, signature_size),
191       &hash,
192       nullptr));
193   brillo::Blob signature;
194   ASSERT_TRUE(PayloadSigner::SignHash(hash,
195                                       kUnittestPrivateKeyPath,
196                                       &signature));
197   ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(
198       payload_path,
199       vector<brillo::Blob>(1, signature),
200       {},
201       payload_path,
202       out_metadata_size));
203   EXPECT_TRUE(PayloadSigner::VerifySignedPayload(
204       payload_path,
205       kUnittestPublicKeyPath));
206 }
207 
SignGeneratedShellPayload(SignatureTest signature_test,const string & payload_path)208 static void SignGeneratedShellPayload(SignatureTest signature_test,
209                                       const string& payload_path) {
210   string private_key_path = kUnittestPrivateKeyPath;
211   if (signature_test == kSignatureGeneratedShellBadKey) {
212     ASSERT_TRUE(utils::MakeTempFile("key.XXXXXX",
213                                     &private_key_path,
214                                     nullptr));
215   } else {
216     ASSERT_TRUE(signature_test == kSignatureGeneratedShell ||
217                 signature_test == kSignatureGeneratedShellRotateCl1 ||
218                 signature_test == kSignatureGeneratedShellRotateCl2);
219   }
220   ScopedPathUnlinker key_unlinker(private_key_path);
221   key_unlinker.set_should_remove(signature_test ==
222                                  kSignatureGeneratedShellBadKey);
223   // Generates a new private key that will not match the public key.
224   if (signature_test == kSignatureGeneratedShellBadKey) {
225     LOG(INFO) << "Generating a mismatched private key.";
226     ASSERT_EQ(0, System(base::StringPrintf(
227         "openssl genrsa -out %s 2048", private_key_path.c_str())));
228   }
229   int signature_size = GetSignatureSize(private_key_path);
230   string hash_file;
231   ASSERT_TRUE(utils::MakeTempFile("hash.XXXXXX", &hash_file, nullptr));
232   ScopedPathUnlinker hash_unlinker(hash_file);
233   string signature_size_string;
234   if (signature_test == kSignatureGeneratedShellRotateCl1 ||
235       signature_test == kSignatureGeneratedShellRotateCl2)
236     signature_size_string = base::StringPrintf("%d:%d",
237                                                signature_size, signature_size);
238   else
239     signature_size_string = base::StringPrintf("%d", signature_size);
240   ASSERT_EQ(0,
241             System(base::StringPrintf(
242                 "./delta_generator -in_file=%s -signature_size=%s "
243                 "-out_hash_file=%s",
244                 payload_path.c_str(),
245                 signature_size_string.c_str(),
246                 hash_file.c_str())));
247 
248   // Pad the hash
249   brillo::Blob hash;
250   ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
251   ASSERT_TRUE(PayloadVerifier::PadRSA2048SHA256Hash(&hash));
252   ASSERT_TRUE(test_utils::WriteFileVector(hash_file, hash));
253 
254   string sig_file;
255   ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file, nullptr));
256   ScopedPathUnlinker sig_unlinker(sig_file);
257   ASSERT_EQ(0,
258             System(base::StringPrintf(
259                 "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
260                 private_key_path.c_str(),
261                 hash_file.c_str(),
262                 sig_file.c_str())));
263   string sig_file2;
264   ASSERT_TRUE(utils::MakeTempFile("signature.XXXXXX", &sig_file2, nullptr));
265   ScopedPathUnlinker sig2_unlinker(sig_file2);
266   if (signature_test == kSignatureGeneratedShellRotateCl1 ||
267       signature_test == kSignatureGeneratedShellRotateCl2) {
268     ASSERT_EQ(0,
269               System(base::StringPrintf(
270                   "openssl rsautl -raw -sign -inkey %s -in %s -out %s",
271                   kUnittestPrivateKey2Path,
272                   hash_file.c_str(),
273                   sig_file2.c_str())));
274     // Append second sig file to first path
275     sig_file += ":" + sig_file2;
276   }
277 
278   ASSERT_EQ(0,
279             System(base::StringPrintf(
280                 "./delta_generator -in_file=%s -signature_file=%s "
281                 "-out_file=%s",
282                 payload_path.c_str(),
283                 sig_file.c_str(),
284                 payload_path.c_str())));
285   int verify_result =
286       System(base::StringPrintf(
287           "./delta_generator -in_file=%s -public_key=%s -public_key_version=%d",
288           payload_path.c_str(),
289           signature_test == kSignatureGeneratedShellRotateCl2 ?
290           kUnittestPublicKey2Path : kUnittestPublicKeyPath,
291           signature_test == kSignatureGeneratedShellRotateCl2 ? 2 : 1));
292   if (signature_test == kSignatureGeneratedShellBadKey) {
293     ASSERT_NE(0, verify_result);
294   } else {
295     ASSERT_EQ(0, verify_result);
296   }
297 }
298 
GenerateDeltaFile(bool full_kernel,bool full_rootfs,bool noop,ssize_t chunk_size,SignatureTest signature_test,DeltaState * state,uint32_t minor_version)299 static void GenerateDeltaFile(bool full_kernel,
300                               bool full_rootfs,
301                               bool noop,
302                               ssize_t chunk_size,
303                               SignatureTest signature_test,
304                               DeltaState *state,
305                               uint32_t minor_version) {
306   EXPECT_TRUE(utils::MakeTempFile("a_img.XXXXXX", &state->a_img, nullptr));
307   EXPECT_TRUE(utils::MakeTempFile("b_img.XXXXXX", &state->b_img, nullptr));
308 
309   // result_img is used in minor version 2. Instead of applying the update
310   // in-place on A, we apply it to a new image, result_img.
311   EXPECT_TRUE(
312       utils::MakeTempFile("result_img.XXXXXX", &state->result_img, nullptr));
313   test_utils::CreateExtImageAtPath(state->a_img, nullptr);
314 
315   state->image_size = utils::FileSize(state->a_img);
316 
317   // Create ImageInfo A & B
318   ImageInfo old_image_info;
319   ImageInfo new_image_info;
320 
321   if (!full_rootfs) {
322     old_image_info.set_channel("src-channel");
323     old_image_info.set_board("src-board");
324     old_image_info.set_version("src-version");
325     old_image_info.set_key("src-key");
326     old_image_info.set_build_channel("src-build-channel");
327     old_image_info.set_build_version("src-build-version");
328   }
329 
330   new_image_info.set_channel("test-channel");
331   new_image_info.set_board("test-board");
332   new_image_info.set_version("test-version");
333   new_image_info.set_key("test-key");
334   new_image_info.set_build_channel("test-build-channel");
335   new_image_info.set_build_version("test-build-version");
336 
337   // Make some changes to the A image.
338   {
339     string a_mnt;
340     ScopedLoopMounter b_mounter(state->a_img, &a_mnt, 0);
341 
342     brillo::Blob hardtocompress;
343     while (hardtocompress.size() < 3 * kBlockSize) {
344       hardtocompress.insert(hardtocompress.end(),
345                             std::begin(kRandomString), std::end(kRandomString));
346     }
347     EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
348                                                     a_mnt.c_str()).c_str(),
349                                  hardtocompress.data(),
350                                  hardtocompress.size()));
351 
352     brillo::Blob zeros(16 * 1024, 0);
353     EXPECT_EQ(static_cast<int>(zeros.size()),
354               base::WriteFile(base::FilePath(base::StringPrintf(
355                                   "%s/move-to-sparse", a_mnt.c_str())),
356                               reinterpret_cast<const char*>(zeros.data()),
357                               zeros.size()));
358 
359     EXPECT_TRUE(
360         WriteSparseFile(base::StringPrintf("%s/move-from-sparse",
361                                            a_mnt.c_str()), 16 * 1024));
362 
363     EXPECT_EQ(0,
364               System(base::StringPrintf("dd if=/dev/zero of=%s/move-semi-sparse"
365                                         " bs=1 seek=4096 count=1 status=none",
366                                         a_mnt.c_str()).c_str()));
367 
368     // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
369     // patch fails to zero out the final block.
370     brillo::Blob ones(1024 * 1024, 0xff);
371     EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/ones",
372                                                     a_mnt.c_str()).c_str(),
373                                  ones.data(),
374                                  ones.size()));
375   }
376 
377   if (noop) {
378     EXPECT_TRUE(base::CopyFile(base::FilePath(state->a_img),
379                                base::FilePath(state->b_img)));
380     old_image_info = new_image_info;
381   } else {
382     if (minor_version == kSourceMinorPayloadVersion) {
383       // Create a result image with image_size bytes of garbage.
384       brillo::Blob ones(state->image_size, 0xff);
385       EXPECT_TRUE(utils::WriteFile(state->result_img.c_str(),
386                                    ones.data(),
387                                    ones.size()));
388       EXPECT_EQ(utils::FileSize(state->a_img),
389                 utils::FileSize(state->result_img));
390     }
391 
392     test_utils::CreateExtImageAtPath(state->b_img, nullptr);
393 
394     // Make some changes to the B image.
395     string b_mnt;
396     ScopedLoopMounter b_mounter(state->b_img, &b_mnt, 0);
397 
398     EXPECT_EQ(0, System(base::StringPrintf("cp %s/hello %s/hello2",
399                                            b_mnt.c_str(),
400                                            b_mnt.c_str()).c_str()));
401     EXPECT_EQ(0, System(base::StringPrintf("rm %s/hello",
402                                            b_mnt.c_str()).c_str()));
403     EXPECT_EQ(0, System(base::StringPrintf("mv %s/hello2 %s/hello",
404                                            b_mnt.c_str(),
405                                            b_mnt.c_str()).c_str()));
406     EXPECT_EQ(0, System(base::StringPrintf("echo foo > %s/foo",
407                                            b_mnt.c_str()).c_str()));
408     EXPECT_EQ(0, System(base::StringPrintf("touch %s/emptyfile",
409                                            b_mnt.c_str()).c_str()));
410     EXPECT_TRUE(WriteSparseFile(base::StringPrintf("%s/fullsparse",
411                                                    b_mnt.c_str()),
412                                                    1024 * 1024));
413 
414     EXPECT_TRUE(
415         WriteSparseFile(base::StringPrintf("%s/move-to-sparse", b_mnt.c_str()),
416                         16 * 1024));
417 
418     brillo::Blob zeros(16 * 1024, 0);
419     EXPECT_EQ(static_cast<int>(zeros.size()),
420               base::WriteFile(base::FilePath(base::StringPrintf(
421                                   "%s/move-from-sparse", b_mnt.c_str())),
422                               reinterpret_cast<const char*>(zeros.data()),
423                               zeros.size()));
424 
425     EXPECT_EQ(0, System(base::StringPrintf("dd if=/dev/zero "
426                                            "of=%s/move-semi-sparse "
427                                            "bs=1 seek=4096 count=1 status=none",
428                                            b_mnt.c_str()).c_str()));
429 
430     EXPECT_EQ(0, System(base::StringPrintf("dd if=/dev/zero "
431                                            "of=%s/partsparse bs=1 "
432                                            "seek=4096 count=1 status=none",
433                                            b_mnt.c_str()).c_str()));
434     EXPECT_EQ(0, System(base::StringPrintf("cp %s/srchardlink0 %s/tmp && "
435                                            "mv %s/tmp %s/srchardlink1",
436                                            b_mnt.c_str(),
437                                            b_mnt.c_str(),
438                                            b_mnt.c_str(),
439                                            b_mnt.c_str()).c_str()));
440     EXPECT_EQ(0, System(
441         base::StringPrintf("rm %s/boguslink && echo foobar > %s/boguslink",
442                            b_mnt.c_str(), b_mnt.c_str()).c_str()));
443 
444     brillo::Blob hardtocompress;
445     while (hardtocompress.size() < 3 * kBlockSize) {
446       hardtocompress.insert(hardtocompress.end(),
447                             std::begin(kRandomString), std::end(kRandomString));
448     }
449     EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
450                                               b_mnt.c_str()).c_str(),
451                                  hardtocompress.data(),
452                                  hardtocompress.size()));
453   }
454 
455   string old_kernel;
456   EXPECT_TRUE(utils::MakeTempFile("old_kernel.XXXXXX",
457                                   &state->old_kernel,
458                                   nullptr));
459 
460   string new_kernel;
461   EXPECT_TRUE(utils::MakeTempFile("new_kernel.XXXXXX",
462                                   &state->new_kernel,
463                                   nullptr));
464 
465   string result_kernel;
466   EXPECT_TRUE(utils::MakeTempFile("result_kernel.XXXXXX",
467                                   &state->result_kernel,
468                                   nullptr));
469 
470   state->kernel_size = kDefaultKernelSize;
471   state->old_kernel_data.resize(kDefaultKernelSize);
472   state->new_kernel_data.resize(state->old_kernel_data.size());
473   state->result_kernel_data.resize(state->old_kernel_data.size());
474   test_utils::FillWithData(&state->old_kernel_data);
475   test_utils::FillWithData(&state->new_kernel_data);
476   test_utils::FillWithData(&state->result_kernel_data);
477 
478   // change the new kernel data
479   std::copy(std::begin(kNewData), std::end(kNewData),
480             state->new_kernel_data.begin());
481 
482   if (noop) {
483     state->old_kernel_data = state->new_kernel_data;
484   }
485 
486   // Write kernels to disk
487   EXPECT_TRUE(utils::WriteFile(state->old_kernel.c_str(),
488                                state->old_kernel_data.data(),
489                                state->old_kernel_data.size()));
490   EXPECT_TRUE(utils::WriteFile(state->new_kernel.c_str(),
491                                state->new_kernel_data.data(),
492                                state->new_kernel_data.size()));
493   EXPECT_TRUE(utils::WriteFile(state->result_kernel.c_str(),
494                                state->result_kernel_data.data(),
495                                state->result_kernel_data.size()));
496 
497   EXPECT_TRUE(utils::MakeTempFile("delta.XXXXXX",
498                                   &state->delta_path,
499                                   nullptr));
500   LOG(INFO) << "delta path: " << state->delta_path;
501   {
502     const string private_key =
503         signature_test == kSignatureGenerator ? kUnittestPrivateKeyPath : "";
504 
505     PayloadGenerationConfig payload_config;
506     payload_config.is_delta = !full_rootfs;
507     payload_config.hard_chunk_size = chunk_size;
508     payload_config.rootfs_partition_size = kRootFSPartitionSize;
509     payload_config.version.major = kChromeOSMajorPayloadVersion;
510     payload_config.version.minor = minor_version;
511     if (!full_rootfs) {
512       payload_config.source.partitions.emplace_back(kLegacyPartitionNameRoot);
513       payload_config.source.partitions.emplace_back(kLegacyPartitionNameKernel);
514       payload_config.source.partitions.front().path = state->a_img;
515       if (!full_kernel)
516         payload_config.source.partitions.back().path = state->old_kernel;
517       payload_config.source.image_info = old_image_info;
518       EXPECT_TRUE(payload_config.source.LoadImageSize());
519       for (PartitionConfig& part : payload_config.source.partitions)
520         EXPECT_TRUE(part.OpenFilesystem());
521     } else {
522       if (payload_config.hard_chunk_size == -1)
523         // Use 1 MiB chunk size for the full unittests.
524         payload_config.hard_chunk_size = 1024 * 1024;
525     }
526     payload_config.target.partitions.emplace_back(kLegacyPartitionNameRoot);
527     payload_config.target.partitions.back().path = state->b_img;
528     payload_config.target.partitions.emplace_back(kLegacyPartitionNameKernel);
529     payload_config.target.partitions.back().path = state->new_kernel;
530     payload_config.target.image_info = new_image_info;
531     EXPECT_TRUE(payload_config.target.LoadImageSize());
532     for (PartitionConfig& part : payload_config.target.partitions)
533       EXPECT_TRUE(part.OpenFilesystem());
534 
535     EXPECT_TRUE(payload_config.Validate());
536     EXPECT_TRUE(
537         GenerateUpdatePayloadFile(
538             payload_config,
539             state->delta_path,
540             private_key,
541             &state->metadata_size));
542   }
543   // Extend the "partitions" holding the file system a bit.
544   EXPECT_EQ(0, HANDLE_EINTR(truncate(state->a_img.c_str(),
545                                      state->image_size + 1024 * 1024)));
546   EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
547             utils::FileSize(state->a_img));
548   EXPECT_EQ(0, HANDLE_EINTR(truncate(state->b_img.c_str(),
549                                      state->image_size + 1024 * 1024)));
550   EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
551             utils::FileSize(state->b_img));
552 
553   if (signature_test == kSignatureGeneratedPlaceholder ||
554       signature_test == kSignatureGeneratedPlaceholderMismatch) {
555     int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
556     LOG(INFO) << "Inserting placeholder signature.";
557     ASSERT_TRUE(InsertSignaturePlaceholder(signature_size, state->delta_path,
558                                            &state->metadata_size));
559 
560     if (signature_test == kSignatureGeneratedPlaceholderMismatch) {
561       signature_size -= 1;
562       LOG(INFO) << "Inserting mismatched placeholder signature.";
563       ASSERT_FALSE(InsertSignaturePlaceholder(signature_size, state->delta_path,
564                                               &state->metadata_size));
565       return;
566     }
567   }
568 
569   if (signature_test == kSignatureGenerated ||
570       signature_test == kSignatureGeneratedPlaceholder ||
571       signature_test == kSignatureGeneratedPlaceholderMismatch) {
572     // Generate the signed payload and update the metadata size in state to
573     // reflect the new size after adding the signature operation to the
574     // manifest.
575     LOG(INFO) << "Signing payload.";
576     SignGeneratedPayload(state->delta_path, &state->metadata_size);
577   } else if (signature_test == kSignatureGeneratedShell ||
578              signature_test == kSignatureGeneratedShellBadKey ||
579              signature_test == kSignatureGeneratedShellRotateCl1 ||
580              signature_test == kSignatureGeneratedShellRotateCl2) {
581     SignGeneratedShellPayload(signature_test, state->delta_path);
582   }
583 }
584 
ApplyDeltaFile(bool full_kernel,bool full_rootfs,bool noop,SignatureTest signature_test,DeltaState * state,bool hash_checks_mandatory,OperationHashTest op_hash_test,DeltaPerformer ** performer,uint32_t minor_version)585 static void ApplyDeltaFile(bool full_kernel, bool full_rootfs, bool noop,
586                            SignatureTest signature_test, DeltaState* state,
587                            bool hash_checks_mandatory,
588                            OperationHashTest op_hash_test,
589                            DeltaPerformer** performer,
590                            uint32_t minor_version) {
591   // Check the metadata.
592   {
593     DeltaArchiveManifest manifest;
594     EXPECT_TRUE(PayloadSigner::LoadPayloadMetadata(state->delta_path,
595                                                    nullptr,
596                                                    &manifest,
597                                                    nullptr,
598                                                    &state->metadata_size,
599                                                    nullptr));
600     LOG(INFO) << "Metadata size: " << state->metadata_size;
601     EXPECT_TRUE(utils::ReadFile(state->delta_path, &state->delta));
602 
603     if (signature_test == kSignatureNone) {
604       EXPECT_FALSE(manifest.has_signatures_offset());
605       EXPECT_FALSE(manifest.has_signatures_size());
606     } else {
607       EXPECT_TRUE(manifest.has_signatures_offset());
608       EXPECT_TRUE(manifest.has_signatures_size());
609       Signatures sigs_message;
610       EXPECT_TRUE(sigs_message.ParseFromArray(
611           &state->delta[state->metadata_size + manifest.signatures_offset()],
612           manifest.signatures_size()));
613       if (signature_test == kSignatureGeneratedShellRotateCl1 ||
614           signature_test == kSignatureGeneratedShellRotateCl2)
615         EXPECT_EQ(2, sigs_message.signatures_size());
616       else
617         EXPECT_EQ(1, sigs_message.signatures_size());
618       const Signatures_Signature& signature = sigs_message.signatures(0);
619       EXPECT_EQ(1U, signature.version());
620 
621       uint64_t expected_sig_data_length = 0;
622       vector<string> key_paths{kUnittestPrivateKeyPath};
623       if (signature_test == kSignatureGeneratedShellRotateCl1 ||
624           signature_test == kSignatureGeneratedShellRotateCl2) {
625         key_paths.push_back(kUnittestPrivateKey2Path);
626       }
627       EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
628           key_paths,
629           &expected_sig_data_length));
630       EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
631       EXPECT_FALSE(signature.data().empty());
632     }
633 
634     if (noop) {
635       EXPECT_EQ(0, manifest.install_operations_size());
636       EXPECT_EQ(1, manifest.kernel_install_operations_size());
637     }
638 
639     if (full_kernel) {
640       EXPECT_FALSE(manifest.has_old_kernel_info());
641     } else {
642       EXPECT_EQ(state->old_kernel_data.size(),
643                 manifest.old_kernel_info().size());
644       EXPECT_FALSE(manifest.old_kernel_info().hash().empty());
645     }
646 
647     EXPECT_EQ(manifest.new_image_info().channel(), "test-channel");
648     EXPECT_EQ(manifest.new_image_info().board(), "test-board");
649     EXPECT_EQ(manifest.new_image_info().version(), "test-version");
650     EXPECT_EQ(manifest.new_image_info().key(), "test-key");
651     EXPECT_EQ(manifest.new_image_info().build_channel(), "test-build-channel");
652     EXPECT_EQ(manifest.new_image_info().build_version(), "test-build-version");
653 
654     if (!full_rootfs) {
655       if (noop) {
656         EXPECT_EQ(manifest.old_image_info().channel(), "test-channel");
657         EXPECT_EQ(manifest.old_image_info().board(), "test-board");
658         EXPECT_EQ(manifest.old_image_info().version(), "test-version");
659         EXPECT_EQ(manifest.old_image_info().key(), "test-key");
660         EXPECT_EQ(manifest.old_image_info().build_channel(),
661                   "test-build-channel");
662         EXPECT_EQ(manifest.old_image_info().build_version(),
663                   "test-build-version");
664       } else {
665         EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
666         EXPECT_EQ(manifest.old_image_info().board(), "src-board");
667         EXPECT_EQ(manifest.old_image_info().version(), "src-version");
668         EXPECT_EQ(manifest.old_image_info().key(), "src-key");
669         EXPECT_EQ(manifest.old_image_info().build_channel(),
670                   "src-build-channel");
671         EXPECT_EQ(manifest.old_image_info().build_version(),
672                   "src-build-version");
673       }
674     }
675 
676 
677     if (full_rootfs) {
678       EXPECT_FALSE(manifest.has_old_rootfs_info());
679       EXPECT_FALSE(manifest.has_old_image_info());
680       EXPECT_TRUE(manifest.has_new_image_info());
681     } else {
682       EXPECT_EQ(state->image_size, manifest.old_rootfs_info().size());
683       EXPECT_FALSE(manifest.old_rootfs_info().hash().empty());
684     }
685 
686     EXPECT_EQ(state->new_kernel_data.size(), manifest.new_kernel_info().size());
687     EXPECT_EQ(state->image_size, manifest.new_rootfs_info().size());
688 
689     EXPECT_FALSE(manifest.new_kernel_info().hash().empty());
690     EXPECT_FALSE(manifest.new_rootfs_info().hash().empty());
691   }
692 
693   MockPrefs prefs;
694   EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize,
695                               state->metadata_size)).WillOnce(Return(true));
696   EXPECT_CALL(prefs, SetInt64(kPrefsManifestSignatureSize, 0))
697       .WillOnce(Return(true));
698   EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
699       .WillRepeatedly(Return(true));
700   EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
701       .WillOnce(Return(false));
702   EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
703       .WillRepeatedly(Return(true));
704   EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataLength, _))
705       .WillRepeatedly(Return(true));
706   EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
707       .WillRepeatedly(Return(true));
708   EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
709       .WillRepeatedly(Return(true));
710   if (op_hash_test == kValidOperationData && signature_test != kSignatureNone) {
711     EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
712         .WillOnce(Return(true));
713   }
714 
715   EXPECT_CALL(state->mock_delegate_, ShouldCancel(_))
716       .WillRepeatedly(Return(false));
717 
718   // Update the A image in place.
719   InstallPlan* install_plan = &state->install_plan;
720   install_plan->hash_checks_mandatory = hash_checks_mandatory;
721   install_plan->metadata_size = state->metadata_size;
722   install_plan->payload_type = (full_kernel && full_rootfs)
723                                    ? InstallPayloadType::kFull
724                                    : InstallPayloadType::kDelta;
725   install_plan->source_slot = 0;
726   install_plan->target_slot = 1;
727 
728   InstallPlan::Partition root_part;
729   root_part.name = kLegacyPartitionNameRoot;
730 
731   InstallPlan::Partition kernel_part;
732   kernel_part.name = kLegacyPartitionNameKernel;
733 
734   LOG(INFO) << "Setting payload metadata size in Omaha  = "
735             << state->metadata_size;
736   ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
737       state->delta.data(),
738       state->metadata_size,
739       kUnittestPrivateKeyPath,
740       &install_plan->metadata_signature));
741   EXPECT_FALSE(install_plan->metadata_signature.empty());
742 
743   *performer = new DeltaPerformer(&prefs,
744                                   &state->fake_boot_control_,
745                                   &state->fake_hardware_,
746                                   &state->mock_delegate_,
747                                   install_plan);
748   EXPECT_TRUE(utils::FileExists(kUnittestPublicKeyPath));
749   (*performer)->set_public_key_path(kUnittestPublicKeyPath);
750   DeltaPerformerIntegrationTest::SetSupportedVersion(*performer, minor_version);
751 
752   EXPECT_EQ(static_cast<off_t>(state->image_size),
753             HashCalculator::RawHashOfFile(
754                 state->a_img,
755                 state->image_size,
756                 &root_part.source_hash));
757   EXPECT_TRUE(HashCalculator::RawHashOfData(
758                   state->old_kernel_data,
759                   &kernel_part.source_hash));
760 
761   // This partitions are normally filed by the FilesystemVerifierAction with
762   // the source hashes used for deltas.
763   install_plan->partitions = {root_part, kernel_part};
764 
765   // With minor version 2, we want the target to be the new image, result_img,
766   // but with version 1, we want to update A in place.
767   string target_root, target_kernel;
768   if (minor_version == kSourceMinorPayloadVersion) {
769     target_root = state->result_img;
770     target_kernel = state->result_kernel;
771   } else {
772     target_root = state->a_img;
773     target_kernel = state->old_kernel;
774   }
775 
776   state->fake_boot_control_.SetPartitionDevice(
777       kLegacyPartitionNameRoot, install_plan->source_slot, state->a_img);
778   state->fake_boot_control_.SetPartitionDevice(
779       kLegacyPartitionNameKernel, install_plan->source_slot, state->old_kernel);
780   state->fake_boot_control_.SetPartitionDevice(
781       kLegacyPartitionNameRoot, install_plan->target_slot, target_root);
782   state->fake_boot_control_.SetPartitionDevice(
783       kLegacyPartitionNameKernel, install_plan->target_slot, target_kernel);
784 
785   ErrorCode expected_error, actual_error;
786   bool continue_writing;
787   switch (op_hash_test) {
788     case kInvalidOperationData: {
789       // Muck with some random offset post the metadata size so that
790       // some operation hash will result in a mismatch.
791       int some_offset = state->metadata_size + 300;
792       LOG(INFO) << "Tampered value at offset: " << some_offset;
793       state->delta[some_offset]++;
794       expected_error = ErrorCode::kDownloadOperationHashMismatch;
795       continue_writing = false;
796       break;
797     }
798 
799     case kValidOperationData:
800     default:
801       // no change.
802       expected_error = ErrorCode::kSuccess;
803       continue_writing = true;
804       break;
805   }
806 
807   // Write at some number of bytes per operation. Arbitrarily chose 5.
808   const size_t kBytesPerWrite = 5;
809   for (size_t i = 0; i < state->delta.size(); i += kBytesPerWrite) {
810     size_t count = std::min(state->delta.size() - i, kBytesPerWrite);
811     bool write_succeeded = ((*performer)->Write(&state->delta[i],
812                                                 count,
813                                                 &actual_error));
814     // Normally write_succeeded should be true every time and
815     // actual_error should be ErrorCode::kSuccess. If so, continue the loop.
816     // But if we seeded an operation hash error above, then write_succeeded
817     // will be false. The failure may happen at any operation n. So, all
818     // Writes until n-1 should succeed and the nth operation will fail with
819     // actual_error. In this case, we should bail out of the loop because
820     // we cannot proceed applying the delta.
821     if (!write_succeeded) {
822       LOG(INFO) << "Write failed. Checking if it failed with expected error";
823       EXPECT_EQ(expected_error, actual_error);
824       if (!continue_writing) {
825         LOG(INFO) << "Cannot continue writing. Bailing out.";
826         break;
827       }
828     }
829 
830     EXPECT_EQ(ErrorCode::kSuccess, actual_error);
831   }
832 
833   // If we had continued all the way through, Close should succeed.
834   // Otherwise, it should fail. Check appropriately.
835   bool close_result = (*performer)->Close();
836   if (continue_writing)
837     EXPECT_EQ(0, close_result);
838   else
839     EXPECT_LE(0, close_result);
840 }
841 
VerifyPayloadResult(DeltaPerformer * performer,DeltaState * state,ErrorCode expected_result,uint32_t minor_version)842 void VerifyPayloadResult(DeltaPerformer* performer,
843                          DeltaState* state,
844                          ErrorCode expected_result,
845                          uint32_t minor_version) {
846   if (!performer) {
847     EXPECT_TRUE(!"Skipping payload verification since performer is null.");
848     return;
849   }
850 
851   int expected_times = (expected_result == ErrorCode::kSuccess) ? 1 : 0;
852   EXPECT_CALL(state->mock_delegate_, DownloadComplete()).Times(expected_times);
853 
854   LOG(INFO) << "Verifying payload for expected result "
855             << expected_result;
856   EXPECT_EQ(expected_result, performer->VerifyPayload(
857       HashCalculator::HashOfData(state->delta),
858       state->delta.size()));
859   LOG(INFO) << "Verified payload.";
860 
861   if (expected_result != ErrorCode::kSuccess) {
862     // no need to verify new partition if VerifyPayload failed.
863     return;
864   }
865 
866   brillo::Blob updated_kernel_partition;
867   if (minor_version == kSourceMinorPayloadVersion) {
868     CompareFilesByBlock(state->result_kernel, state->new_kernel,
869                         state->kernel_size);
870     CompareFilesByBlock(state->result_img, state->b_img,
871                         state->image_size);
872     EXPECT_TRUE(utils::ReadFile(state->result_kernel,
873                                 &updated_kernel_partition));
874   } else {
875     CompareFilesByBlock(state->old_kernel, state->new_kernel,
876                         state->kernel_size);
877     CompareFilesByBlock(state->a_img, state->b_img,
878                         state->image_size);
879     EXPECT_TRUE(utils::ReadFile(state->old_kernel, &updated_kernel_partition));
880   }
881 
882   ASSERT_GE(updated_kernel_partition.size(), arraysize(kNewData));
883   EXPECT_TRUE(std::equal(std::begin(kNewData), std::end(kNewData),
884                          updated_kernel_partition.begin()));
885 
886   const auto& partitions = state->install_plan.partitions;
887   EXPECT_EQ(2U, partitions.size());
888   EXPECT_EQ(kLegacyPartitionNameRoot, partitions[0].name);
889   EXPECT_EQ(kLegacyPartitionNameKernel, partitions[1].name);
890 
891   EXPECT_EQ(kDefaultKernelSize, partitions[1].target_size);
892   brillo::Blob expected_new_kernel_hash;
893   EXPECT_TRUE(HashCalculator::RawHashOfData(state->new_kernel_data,
894                                             &expected_new_kernel_hash));
895   EXPECT_EQ(expected_new_kernel_hash, partitions[1].target_hash);
896 
897   EXPECT_EQ(state->image_size, partitions[0].target_size);
898   brillo::Blob expected_new_rootfs_hash;
899   EXPECT_EQ(static_cast<off_t>(state->image_size),
900             HashCalculator::RawHashOfFile(state->b_img,
901                                           state->image_size,
902                                           &expected_new_rootfs_hash));
903   EXPECT_EQ(expected_new_rootfs_hash, partitions[0].target_hash);
904 }
905 
VerifyPayload(DeltaPerformer * performer,DeltaState * state,SignatureTest signature_test,uint32_t minor_version)906 void VerifyPayload(DeltaPerformer* performer,
907                    DeltaState* state,
908                    SignatureTest signature_test,
909                    uint32_t minor_version) {
910   ErrorCode expected_result = ErrorCode::kSuccess;
911   switch (signature_test) {
912     case kSignatureNone:
913       expected_result = ErrorCode::kSignedDeltaPayloadExpectedError;
914       break;
915     case kSignatureGeneratedShellBadKey:
916       expected_result = ErrorCode::kDownloadPayloadPubKeyVerificationError;
917       break;
918     default: break;  // appease gcc
919   }
920 
921   VerifyPayloadResult(performer, state, expected_result, minor_version);
922 }
923 
DoSmallImageTest(bool full_kernel,bool full_rootfs,bool noop,ssize_t chunk_size,SignatureTest signature_test,bool hash_checks_mandatory,uint32_t minor_version)924 void DoSmallImageTest(bool full_kernel, bool full_rootfs, bool noop,
925                       ssize_t chunk_size,
926                       SignatureTest signature_test,
927                       bool hash_checks_mandatory, uint32_t minor_version) {
928   DeltaState state;
929   DeltaPerformer *performer = nullptr;
930   GenerateDeltaFile(full_kernel, full_rootfs, noop, chunk_size,
931                     signature_test, &state, minor_version);
932 
933   ScopedPathUnlinker a_img_unlinker(state.a_img);
934   ScopedPathUnlinker b_img_unlinker(state.b_img);
935   ScopedPathUnlinker new_img_unlinker(state.result_img);
936   ScopedPathUnlinker delta_unlinker(state.delta_path);
937   ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
938   ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
939   ScopedPathUnlinker result_kernel_unlinker(state.result_kernel);
940   ApplyDeltaFile(full_kernel, full_rootfs, noop, signature_test,
941                  &state, hash_checks_mandatory, kValidOperationData,
942                  &performer, minor_version);
943   VerifyPayload(performer, &state, signature_test, minor_version);
944   delete performer;
945 }
946 
DoOperationHashMismatchTest(OperationHashTest op_hash_test,bool hash_checks_mandatory)947 void DoOperationHashMismatchTest(OperationHashTest op_hash_test,
948                                  bool hash_checks_mandatory) {
949   DeltaState state;
950   uint64_t minor_version = kFullPayloadMinorVersion;
951   GenerateDeltaFile(true, true, false, -1, kSignatureGenerated, &state,
952                     minor_version);
953   ScopedPathUnlinker a_img_unlinker(state.a_img);
954   ScopedPathUnlinker b_img_unlinker(state.b_img);
955   ScopedPathUnlinker delta_unlinker(state.delta_path);
956   ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
957   ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
958   DeltaPerformer *performer = nullptr;
959   ApplyDeltaFile(true, true, false, kSignatureGenerated, &state,
960                  hash_checks_mandatory, op_hash_test, &performer,
961                  minor_version);
962   delete performer;
963 }
964 
965 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageTest)966 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageTest) {
967   DoSmallImageTest(false, false, false, -1, kSignatureGenerator,
968                    false, kInPlaceMinorPayloadVersion);
969 }
970 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignaturePlaceholderTest)971 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignaturePlaceholderTest) {
972   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedPlaceholder,
973                    false, kInPlaceMinorPayloadVersion);
974 }
975 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignaturePlaceholderMismatchTest)976 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignaturePlaceholderMismatchTest) {
977   DeltaState state;
978   GenerateDeltaFile(false, false, false, -1,
979                     kSignatureGeneratedPlaceholderMismatch, &state,
980                     kInPlaceMinorPayloadVersion);
981 }
982 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageChunksTest)983 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageChunksTest) {
984   DoSmallImageTest(false, false, false, kBlockSize, kSignatureGenerator,
985                    false, kInPlaceMinorPayloadVersion);
986 }
987 
TEST(DeltaPerformerIntegrationTest,RunAsRootFullKernelSmallImageTest)988 TEST(DeltaPerformerIntegrationTest, RunAsRootFullKernelSmallImageTest) {
989   DoSmallImageTest(true, false, false, -1, kSignatureGenerator,
990                    false, kInPlaceMinorPayloadVersion);
991 }
992 
TEST(DeltaPerformerIntegrationTest,RunAsRootFullSmallImageTest)993 TEST(DeltaPerformerIntegrationTest, RunAsRootFullSmallImageTest) {
994   DoSmallImageTest(true, true, false, -1, kSignatureGenerator,
995                    true, kFullPayloadMinorVersion);
996 }
997 
TEST(DeltaPerformerIntegrationTest,RunAsRootNoopSmallImageTest)998 TEST(DeltaPerformerIntegrationTest, RunAsRootNoopSmallImageTest) {
999   DoSmallImageTest(false, false, true, -1, kSignatureGenerator,
1000                    false, kInPlaceMinorPayloadVersion);
1001 }
1002 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignNoneTest)1003 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignNoneTest) {
1004   DoSmallImageTest(false, false, false, -1, kSignatureNone,
1005                    false, kInPlaceMinorPayloadVersion);
1006 }
1007 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedTest)1008 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedTest) {
1009   DoSmallImageTest(false, false, false, -1, kSignatureGenerated,
1010                    true, kInPlaceMinorPayloadVersion);
1011 }
1012 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedShellTest)1013 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellTest) {
1014   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShell,
1015                    false, kInPlaceMinorPayloadVersion);
1016 }
1017 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedShellBadKeyTest)1018 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
1019   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellBadKey,
1020                    false, kInPlaceMinorPayloadVersion);
1021 }
1022 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedShellRotateCl1Test)1023 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
1024   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl1,
1025                    false, kInPlaceMinorPayloadVersion);
1026 }
1027 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedShellRotateCl2Test)1028 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
1029   DoSmallImageTest(false, false, false, -1, kSignatureGeneratedShellRotateCl2,
1030                    false, kInPlaceMinorPayloadVersion);
1031 }
1032 
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSourceOpsTest)1033 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSourceOpsTest) {
1034   DoSmallImageTest(false, false, false, -1, kSignatureGenerator,
1035                    false, kSourceMinorPayloadVersion);
1036 }
1037 
TEST(DeltaPerformerIntegrationTest,RunAsRootMandatoryOperationHashMismatchTest)1038 TEST(DeltaPerformerIntegrationTest, RunAsRootMandatoryOperationHashMismatchTest) {
1039   DoOperationHashMismatchTest(kInvalidOperationData, true);
1040 }
1041 
1042 }  // namespace chromeos_update_engine
1043