Checked reported component version against the signed manifest.

This checks the reported version of the component against the version in
the signed manifest. This is important because otherwise an attacker can
rollback a component by lying about the version.

BUG=chromium:667826
TEST=FEATURES=test emerge-${BOARD} imageloader

Change-Id: Ic84be0cd1f5f934c1abdd2f04b99688cc26d8673
Reviewed-on: https://chromium-review.googlesource.com/425707
Reviewed-by: Eric Caruso <ejcaruso@chromium.org>
Tested-by: Greg Kerr <kerrnel@chromium.org>
Commit-Queue: Greg Kerr <kerrnel@chromium.org>
diff --git a/imageloader_impl.cc b/imageloader_impl.cc
index c28235e..f3b93f9 100644
--- a/imageloader_impl.cc
+++ b/imageloader_impl.cc
@@ -206,6 +206,13 @@
   Component component(component_path);
   if (!component.Init(config_.key)) return false;
 
+  // Check that the reported version matches the component manifest version.
+  if (component.manifest().version != version) {
+    LOG(ERROR) << "Version in signed manifest does not match the reported "
+                  "component version.";
+    return false;
+  }
+
   // Take ownership of the component and verify it.
   base::FilePath version_path(GetVersionPath(name, version));
   // If |version_path| exists but was not the active version, ImageLoader
diff --git a/imageloader_unittest.cc b/imageloader_unittest.cc
index bc7ab9e..575cadc 100644
--- a/imageloader_unittest.cc
+++ b/imageloader_unittest.cc
@@ -66,6 +66,10 @@
   base::FilePath version_dir = comp_dir.Append(kTestDataVersion);
   ASSERT_TRUE(base::DirectoryExists(version_dir));
 
+  // Make sure it actually checks the reported version against the real version.
+  EXPECT_FALSE(loader.RegisterComponent(kTestComponentName, kTestUpdatedVersion,
+                                        GetTestComponentPath().value()));
+
   // Now copy a new version into place.
   EXPECT_TRUE(
       loader.RegisterComponent(kTestComponentName, kTestUpdatedVersion,