AU: Don't allow deltas if the rootfs track is different than the request track.
Currently such deltas are destined to fail because the rootfs hash will be
different than the expected hash.
BUG=9160
TEST=unit tests, tested on device
Change-Id: I588fcedb4a0ae16aca7197f771afab077d78fe05
Review URL: http://codereview.chromium.org/4988002
diff --git a/omaha_request_params.cc b/omaha_request_params.cc
index 6884c83..eaff3d3 100644
--- a/omaha_request_params.cc
+++ b/omaha_request_params.cc
@@ -10,6 +10,7 @@
#include <map>
#include <string>
+#include <vector>
#include <base/file_util.h>
#include <base/string_util.h>
@@ -21,6 +22,7 @@
using std::map;
using std::string;
+using std::vector;
namespace chromeos_update_engine {
@@ -44,28 +46,50 @@
os_platform = OmahaRequestParams::kOsPlatform;
os_version = OmahaRequestParams::kOsVersion;
app_version = in_app_version.empty() ?
- GetLsbValue("CHROMEOS_RELEASE_VERSION", "", NULL) : in_app_version;
+ GetLsbValue("CHROMEOS_RELEASE_VERSION", "", NULL, true) : in_app_version;
os_sp = app_version + "_" + GetMachineType();
- os_board = GetLsbValue("CHROMEOS_RELEASE_BOARD", "", NULL);
+ os_board = GetLsbValue("CHROMEOS_RELEASE_BOARD", "", NULL, true);
app_id = GetLsbValue("CHROMEOS_RELEASE_APPID",
OmahaRequestParams::kAppId,
- NULL);
+ NULL,
+ true);
app_lang = "en-US";
app_track = GetLsbValue(
kUpdateTrackKey,
"",
- &chromeos_update_engine::OmahaRequestDeviceParams::IsValidTrack);
+ &chromeos_update_engine::OmahaRequestDeviceParams::IsValidTrack,
+ true);
hardware_class = GetHardwareClass();
struct stat stbuf;
- // Deltas are only okay if the /.nodelta file does not exist.
- // If we don't know (i.e. stat() returns some unexpected error),
- // then err on the side of caution and say deltas are not okay
+ // Deltas are only okay if the /.nodelta file does not exist. If we don't
+ // know (i.e. stat() returns some unexpected error), then err on the side of
+ // caution and say deltas are not okay.
delta_okay = (stat((root_ + "/.nodelta").c_str(), &stbuf) < 0) &&
(errno == ENOENT);
+ // For now, disable delta updates if the rootfs track is different than the
+ // track that we're sending to the update server because such updates are
+ // destined to fail -- the source rootfs hash will be different than the
+ // expected hash due to the different track in /etc/lsb-release.
+ //
+ // Longer term we should consider an alternative: (a) clients can send
+ // (current_version, current_channel, new_channel) information, or (b) the
+ // build process can make sure releases on separate tracks are identical (i.e,
+ // by not stamping the release with the channel), or (c) the release process
+ // can ensure that different channels get different version numbers.
+ const string rootfs_track = GetLsbValue(
+ kUpdateTrackKey,
+ "",
+ &chromeos_update_engine::OmahaRequestDeviceParams::IsValidTrack,
+ false);
+ delta_okay = delta_okay && rootfs_track == app_track;
+
update_url = in_update_url.empty() ?
- GetLsbValue("CHROMEOS_AUSERVER", OmahaRequestParams::kUpdateUrl, NULL) :
+ GetLsbValue("CHROMEOS_AUSERVER",
+ OmahaRequestParams::kUpdateUrl,
+ NULL,
+ true) :
in_update_url;
return true;
}
@@ -103,14 +127,19 @@
string OmahaRequestDeviceParams::GetLsbValue(const string& key,
const string& default_value,
- ValueValidator validator) const {
- string files[] = {string(utils::kStatefulPartition) + "/etc/lsb-release",
- "/etc/lsb-release"};
- for (unsigned int i = 0; i < arraysize(files); ++i) {
- // TODO(adlr): make sure files checked are owned as root (and all
- // their parents are recursively, too).
+ ValueValidator validator,
+ bool stateful_override) const {
+ vector<string> files;
+ if (stateful_override) {
+ files.push_back(string(utils::kStatefulPartition) + "/etc/lsb-release");
+ }
+ files.push_back("/etc/lsb-release");
+ for (vector<string>::const_iterator it = files.begin();
+ it != files.end(); ++it) {
+ // TODO(adlr): make sure files checked are owned as root (and all their
+ // parents are recursively, too).
string file_data;
- if (!utils::ReadFileToString(root_ + files[i], &file_data))
+ if (!utils::ReadFileToString(root_ + *it, &file_data))
continue;
map<string, string> data = simple_key_value_store::ParseString(file_data);
diff --git a/omaha_request_params.h b/omaha_request_params.h
index b8e2ee5..075ed3f 100644
--- a/omaha_request_params.h
+++ b/omaha_request_params.h
@@ -106,12 +106,13 @@
bool IsValidTrack(const std::string& track) const;
// Fetches the value for a given key from
- // /mnt/stateful_partition/etc/lsb-release if possible. Failing that, it looks
- // for the key in /etc/lsb-release. If |validator| is non-NULL, uses it to
- // validate and ignore invalid valies.
+ // /mnt/stateful_partition/etc/lsb-release if possible and |stateful_override|
+ // is true. Failing that, it looks for the key in /etc/lsb-release. If
+ // |validator| is non-NULL, uses it to validate and ignore invalid valies.
std::string GetLsbValue(const std::string& key,
const std::string& default_value,
- ValueValidator validator) const;
+ ValueValidator validator,
+ bool stateful_override) const;
// Gets the machine type (e.g. "i686").
std::string GetMachineType() const;
diff --git a/omaha_request_params_unittest.cc b/omaha_request_params_unittest.cc
index 77d01d2..fdbf96e 100644
--- a/omaha_request_params_unittest.cc
+++ b/omaha_request_params_unittest.cc
@@ -274,11 +274,37 @@
EXPECT_EQ("0.2.2.3", out.app_version);
EXPECT_EQ("en-US", out.app_lang);
EXPECT_EQ("", out.hardware_class);
- EXPECT_TRUE(out.delta_okay);
+ EXPECT_FALSE(out.delta_okay);
EXPECT_EQ("bartrack", out.app_track);
EXPECT_EQ("http://www.google.com", out.update_url);
}
+TEST_F(OmahaRequestDeviceParamsTest, OverrideSameTrackTest) {
+ ASSERT_TRUE(WriteFileString(
+ kTestDir + "/etc/lsb-release",
+ "CHROMEOS_RELEASE_BOARD=arm-generic\n"
+ "CHROMEOS_RELEASE_FOO=bar\n"
+ "CHROMEOS_RELEASE_VERSION=0.2.2.3\n"
+ "CHROMEOS_RELEASE_TRACK=footrack\n"
+ "CHROMEOS_AUSERVER=http://www.google.com"));
+ ASSERT_TRUE(WriteFileString(
+ kTestDir + utils::kStatefulPartition + "/etc/lsb-release",
+ "CHROMEOS_RELEASE_BOARD=x86-generic\n"
+ "CHROMEOS_RELEASE_TRACK=footrack"));
+ OmahaRequestParams out;
+ EXPECT_TRUE(DoTest(&out, "", ""));
+ EXPECT_EQ("Chrome OS", out.os_platform);
+ EXPECT_EQ(string("0.2.2.3_") + GetMachineType(), out.os_sp);
+ EXPECT_EQ("x86-generic", out.os_board);
+ EXPECT_EQ("{87efface-864d-49a5-9bb3-4b050a7c227a}", out.app_id);
+ EXPECT_EQ("0.2.2.3", out.app_version);
+ EXPECT_EQ("en-US", out.app_lang);
+ EXPECT_EQ("", out.hardware_class);
+ EXPECT_TRUE(out.delta_okay);
+ EXPECT_EQ("footrack", out.app_track);
+ EXPECT_EQ("http://www.google.com", out.update_url);
+}
+
TEST_F(OmahaRequestDeviceParamsTest, SetTrackSimpleTest) {
ASSERT_TRUE(WriteFileString(
kTestDir + "/etc/lsb-release",