Detect if update is already running when updating with file descriptor
If update_engine is triggered with file descriptor when an update is
already running, the running update will be aborted.
Update will be aborted due that existing file descriptor is reset.
Check if update_engine is already running before resetting/closing file
descriptor.
Test: manual, make multiple calls rapidly to java api
UpdateEngine.applyPayload with package in file descriptor
Bug: 178895193
Change-Id: I9c575870b435d2221787eb29d95279328e20fdbe
diff --git a/aosp/update_attempter_android.cc b/aosp/update_attempter_android.cc
index 5c66141..79840e8 100644
--- a/aosp/update_attempter_android.cc
+++ b/aosp/update_attempter_android.cc
@@ -182,7 +182,7 @@
return LogAndSetError(
error, FROM_HERE, "Already processing an update, cancel it first.");
}
- DCHECK(status_ == UpdateStatus::IDLE);
+ DCHECK_EQ(status_, UpdateStatus::IDLE);
std::map<string, string> headers;
if (!ParseKeyValuePairHeaders(key_value_pair_headers, &headers, error)) {
@@ -318,6 +318,18 @@
int64_t payload_size,
const vector<string>& key_value_pair_headers,
brillo::ErrorPtr* error) {
+ // update_engine state must be checked before modifying payload_fd_ otherwise
+ // already running update will be terminated (existing file descriptor will be closed)
+ if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
+ return LogAndSetError(
+ error, FROM_HERE, "An update already applied, waiting for reboot");
+ }
+ if (processor_->IsRunning()) {
+ return LogAndSetError(
+ error, FROM_HERE, "Already processing an update, cancel it first.");
+ }
+ DCHECK_EQ(status_, UpdateStatus::IDLE);
+
payload_fd_.reset(dup(fd));
const string payload_url = "fd://" + std::to_string(payload_fd_.get());