blob: 8c981fb03ce1f3f7e3fd86fa53c9b67c6d73531b [file] [log] [blame] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "oobe_config/rollback_cleanup.h"
#include <memory>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <brillo/syslog_logging.h>
#include <libhwsec/factory/factory_impl.h>
#include <libhwsec/frontend/oobe_config/frontend.h>
#include <oobe_config/metrics/enterprise_rollback_metrics_handler.h>
#include "oobe_config/filesystem/file_handler.h"
#include "oobe_config/metrics/enterprise_rollback_metrics_tracking.h"
namespace oobe_config {
namespace {
void ZeroTpmSpaceIfExists(hwsec::FactoryImpl* hwsec_factory) {
std::unique_ptr<const hwsec::OobeConfigFrontend> hwsec_ =
hwsec_factory->GetOobeConfigFrontend();
hwsec::Status space_ready = hwsec_->IsRollbackSpaceReady();
if (space_ready.ok()) {
hwsec::Status space_reset = hwsec_->ResetRollbackSpace();
if (!space_reset.ok()) {
LOG(ERROR) << space_reset.status();
// TODO(b/262235959): Report failure to reset rollback space.
}
} else if (space_ready->ToTPMRetryAction() ==
hwsec::TPMRetryAction::kSpaceNotFound) {
// Not finding space is expected, log as informational.
LOG(INFO) << space_ready.status();
} else {
LOG(ERROR) << space_ready.status();
}
}
// If encrypted rollback data is present it means that enterprise rollback just
// finished. Should be called only when the device is owned and before cleaning
// up the leftovers.
// We cannot rely on the rollback-happened flag because it may be already
// gone before this code is reached (b/302100343).
bool RollbackJustFinished(const FileHandler* file_handler) {
return file_handler->HasOpensslEncryptedRollbackData() ||
file_handler->HasTpmEncryptedRollbackData();
}
// Should be called only when enterprise rollback has finished, otherwise we may
// be cleaning data too early.
void CleanEnterpriseRollbackMetrics(
const EnterpriseRollbackMetricsHandler* metrics_handler) {
if (metrics_handler->IsTrackingRollback()) {
metrics_handler->StopTrackingRollback();
}
}
// Delete leftovers from a preceding enterprise rollback. Should be called only
// when the device is owned.
void CleanEnterpriseRollbackLeftovers(const FileHandler* file_handler,
hwsec::FactoryImpl* hwsec_factory) {
if (!file_handler->RemoveDecryptedRollbackData()) {
LOG(ERROR) << "Failed to remove decrypted rollback data.";
}
if (!file_handler->RemoveOpensslEncryptedRollbackData()) {
LOG(ERROR) << "Failed to remove OpenSSL encrypted rollback data.";
}
if (!file_handler->RemoveTpmEncryptedRollbackData()) {
LOG(ERROR) << "Failed to remove TPM encrypted rollback data.";
}
ZeroTpmSpaceIfExists(hwsec_factory);
}
// Should be called when the device is not owned to ensure the rollback metrics
// file is deleted if it has not been updated in a while.
void CleanEnterpriseRollbackMetricsIfStale(
const EnterpriseRollbackMetricsHandler* metrics_handler) {
if (metrics_handler->IsTrackingRollback()) {
metrics_handler->CleanRollbackTrackingIfStale();
}
}
base::Version DeviceVersion() {
auto device_version = GetDeviceVersion();
if (!device_version.has_value()) {
return base::Version("");
}
return device_version.value();
}
} // namespace
void RollbackCleanup(
const oobe_config::FileHandler* file_handler,
const oobe_config::EnterpriseRollbackMetricsHandler* metrics_handler,
hwsec::FactoryImpl* hwsec_factory) {
if (file_handler->HasOobeCompletedFlag()) {
// Device is owned so enterprise rollback data is not necessary anymore.
if (RollbackJustFinished(file_handler)) {
metrics_handler->ReportEventNow(
oobe_config::EnterpriseRollbackMetricsHandler::CreateEventData(
EnterpriseRollbackEvent::ROLLBACK_COMPLETED, DeviceVersion()));
CleanEnterpriseRollbackMetrics(metrics_handler);
}
CleanEnterpriseRollbackLeftovers(file_handler, hwsec_factory);
} else {
// If the device is not owned and the enterprise rollback metrics file has
// not been updated in a while, clean it to avoid leaking information.
CleanEnterpriseRollbackMetricsIfStale(metrics_handler);
}
}
} // namespace oobe_config