1 /*
2  * Copyright (C) 2019 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 "gsi_service.h"
18 
19 #include <sys/statvfs.h>
20 #include <sys/vfs.h>
21 #include <unistd.h>
22 
23 #include <array>
24 #include <chrono>
25 #include <string>
26 #include <vector>
27 
28 #include <android-base/errors.h>
29 #include <android-base/file.h>
30 #include <android-base/logging.h>
31 #include <android-base/properties.h>
32 #include <android-base/stringprintf.h>
33 #include <android-base/strings.h>
34 #include <android/gsi/BnImageService.h>
35 #include <android/gsi/IGsiService.h>
36 #include <android/os/IVold.h>
37 #include <binder/IServiceManager.h>
38 #include <binder/LazyServiceRegistrar.h>
39 #include <cutils/android_reboot.h>
40 #include <ext4_utils/ext4_utils.h>
41 #include <fs_mgr.h>
42 #include <libavb/libavb.h>
43 #include <libdm/dm.h>
44 #include <libfiemap/image_manager.h>
45 #include <openssl/sha.h>
46 #include <private/android_filesystem_config.h>
47 #include <selinux/android.h>
48 #include <storage_literals/storage_literals.h>
49 
50 #include "file_paths.h"
51 #include "libgsi_private.h"
52 
53 namespace android {
54 namespace gsi {
55 
56 using namespace std::literals;
57 using namespace android::fs_mgr;
58 using namespace android::fiemap;
59 using namespace android::storage_literals;
60 using android::base::ReadFileToString;
61 using android::base::ReadFullyAtOffset;
62 using android::base::RemoveFileIfExists;
63 using android::base::SetProperty;
64 using android::base::StringPrintf;
65 using android::base::unique_fd;
66 using android::base::WriteStringToFd;
67 using android::base::WriteStringToFile;
68 using android::binder::LazyServiceRegistrar;
69 using android::dm::DeviceMapper;
70 
71 // Default userdata image size.
72 static constexpr int64_t kDefaultUserdataSize = int64_t(2) * 1024 * 1024 * 1024;
73 
74 static bool GetAvbPublicKeyFromFd(int fd, AvbPublicKey* dst);
75 
76 // Fix the file contexts of dsu metadata files.
77 // By default, newly created files inherit the file contexts of their parent
78 // directory. Since globally readable public metadata files are labeled with a
79 // different context, gsi_public_metadata_file, we need to call this function to
80 // fix their contexts after creating them.
RestoreconMetadataFiles()81 static void RestoreconMetadataFiles() {
82     auto flags = SELINUX_ANDROID_RESTORECON_RECURSE | SELINUX_ANDROID_RESTORECON_SKIP_SEHASH;
83     selinux_android_restorecon(DSU_METADATA_PREFIX, flags);
84 }
85 
GsiService()86 GsiService::GsiService() {
87     progress_ = {};
88 }
89 
Register(const std::string & name)90 void GsiService::Register(const std::string& name) {
91     auto lazyRegistrar = LazyServiceRegistrar::getInstance();
92     android::sp<GsiService> service = new GsiService();
93     auto ret = lazyRegistrar.registerService(service, name);
94 
95     if (ret != android::OK) {
96         LOG(FATAL) << "Could not register gsi service: " << ret;
97     }
98 }
99 
100 #define ENFORCE_SYSTEM                      \
101     do {                                    \
102         binder::Status status = CheckUid(); \
103         if (!status.isOk()) return status;  \
104     } while (0)
105 
106 #define ENFORCE_SYSTEM_OR_SHELL                                       \
107     do {                                                              \
108         binder::Status status = CheckUid(AccessLevel::SystemOrShell); \
109         if (!status.isOk()) return status;                            \
110     } while (0)
111 
112 #define ENFORCE_SYSTEM_OR_SHELL_IF_UNLOCK                            \
113     do {                                                             \
114         if (!android::base::EndsWith(GetActiveDsuSlot(), ".lock")) { \
115             ENFORCE_SYSTEM_OR_SHELL;                                 \
116         } else {                                                     \
117             ENFORCE_SYSTEM;                                          \
118         }                                                            \
119     } while (0)
120 
SaveInstallation(const std::string & installation)121 int GsiService::SaveInstallation(const std::string& installation) {
122     auto dsu_slot = GetDsuSlot(installation);
123     auto install_dir_file = DsuInstallDirFile(dsu_slot);
124     auto metadata_dir = android::base::Dirname(install_dir_file);
125     if (access(metadata_dir.c_str(), F_OK) != 0) {
126         if (mkdir(metadata_dir.c_str(), 0777) != 0) {
127             PLOG(ERROR) << "Failed to mkdir " << metadata_dir;
128             return INSTALL_ERROR_GENERIC;
129         }
130     }
131     auto fd = android::base::unique_fd(
132             open(install_dir_file.c_str(), O_RDWR | O_SYNC | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR));
133     if (!WriteStringToFd(installation, fd)) {
134         PLOG(ERROR) << "write failed: " << DsuInstallDirFile(dsu_slot);
135         return INSTALL_ERROR_GENERIC;
136     }
137     return INSTALL_OK;
138 }
139 
140 static bool IsExternalStoragePath(const std::string& path);
141 
openInstall(const std::string & install_dir,int * _aidl_return)142 binder::Status GsiService::openInstall(const std::string& install_dir, int* _aidl_return) {
143     ENFORCE_SYSTEM;
144     std::lock_guard<std::mutex> guard(lock_);
145     if (IsGsiRunning()) {
146         *_aidl_return = IGsiService::INSTALL_ERROR_GENERIC;
147         return binder::Status::ok();
148     }
149     install_dir_ = install_dir;
150     if (int status = ValidateInstallParams(install_dir_)) {
151         *_aidl_return = status;
152         return binder::Status::ok();
153     }
154     std::string message;
155     auto dsu_slot = GetDsuSlot(install_dir_);
156     if (!RemoveFileIfExists(GetCompleteIndication(dsu_slot), &message)) {
157         LOG(ERROR) << message;
158     }
159     // Remember the installation directory before allocate any resource
160     *_aidl_return = SaveInstallation(install_dir_);
161     return binder::Status::ok();
162 }
163 
closeInstall(int * _aidl_return)164 binder::Status GsiService::closeInstall(int* _aidl_return) {
165     ENFORCE_SYSTEM;
166     std::lock_guard<std::mutex> guard(lock_);
167 
168     installer_ = {};
169 
170     auto dsu_slot = GetDsuSlot(install_dir_);
171     std::string file = GetCompleteIndication(dsu_slot);
172     if (!WriteStringToFile("OK", file)) {
173         PLOG(ERROR) << "write failed: " << file;
174         *_aidl_return = IGsiService::INSTALL_ERROR_GENERIC;
175         return binder::Status::ok();
176     }
177 
178     // Create installation complete marker files, but set disabled immediately.
179     if (!WriteStringToFile(dsu_slot, kDsuActiveFile)) {
180         PLOG(ERROR) << "cannot write active DSU slot (" << dsu_slot << "): " << kDsuActiveFile;
181         *_aidl_return = IGsiService::INSTALL_ERROR_GENERIC;
182         return binder::Status::ok();
183     }
184     RestoreconMetadataFiles();
185 
186     // DisableGsi() creates the DSU install status file and mark it as "disabled".
187     if (!DisableGsi()) {
188         PLOG(ERROR) << "cannot write DSU status file: " << kDsuInstallStatusFile;
189         *_aidl_return = IGsiService::INSTALL_ERROR_GENERIC;
190         return binder::Status::ok();
191     }
192 
193     SetProperty(kGsiInstalledProp, "1");
194     *_aidl_return = IGsiService::INSTALL_OK;
195     return binder::Status::ok();
196 }
197 
createPartition(const::std::string & name,int64_t size,bool readOnly,int32_t * _aidl_return)198 binder::Status GsiService::createPartition(const ::std::string& name, int64_t size, bool readOnly,
199                                            int32_t* _aidl_return) {
200     ENFORCE_SYSTEM;
201     std::lock_guard<std::mutex> guard(lock_);
202 
203     if (install_dir_.empty()) {
204         PLOG(ERROR) << "open is required for createPartition";
205         *_aidl_return = INSTALL_ERROR_GENERIC;
206         return binder::Status::ok();
207     }
208 
209     // Do some precursor validation on the arguments before diving into the
210     // install process.
211     if (size % LP_SECTOR_SIZE) {
212         LOG(ERROR) << " size " << size << " is not a multiple of " << LP_SECTOR_SIZE;
213         *_aidl_return = INSTALL_ERROR_GENERIC;
214         return binder::Status::ok();
215     }
216 
217     if (size == 0 && name == "userdata") {
218         size = kDefaultUserdataSize;
219     }
220 
221     if (name == "userdata") {
222         auto dsu_slot = GetDsuSlot(install_dir_);
223         auto key_dir = DefaultDsuMetadataKeyDir(dsu_slot);
224         auto key_dir_file = DsuMetadataKeyDirFile(dsu_slot);
225         if (!android::base::WriteStringToFile(key_dir, key_dir_file)) {
226             PLOG(ERROR) << "write failed: " << key_dir_file;
227             *_aidl_return = INSTALL_ERROR_GENERIC;
228             return binder::Status::ok();
229         }
230         RestoreconMetadataFiles();
231     }
232 
233     installer_ = std::make_unique<PartitionInstaller>(this, install_dir_, name,
234                                                       GetDsuSlot(install_dir_), size, readOnly);
235     progress_ = {};
236     *_aidl_return = installer_->StartInstall();
237     return binder::Status::ok();
238 }
239 
closePartition(int32_t * _aidl_return)240 binder::Status GsiService::closePartition(int32_t* _aidl_return) {
241     ENFORCE_SYSTEM;
242     std::lock_guard<std::mutex> guard(lock_);
243 
244     if (installer_ == nullptr) {
245         LOG(ERROR) << "createPartition() has to be called before closePartition()";
246         *_aidl_return = IGsiService::INSTALL_ERROR_GENERIC;
247         return binder::Status::ok();
248     }
249     // It is important to not reset |installer_| here because other methods such
250     // as isGsiInstallInProgress() relies on the state of |installer_|.
251     // TODO: Maybe don't do this, use a dedicated |in_progress_| flag?
252     *_aidl_return = installer_->FinishInstall();
253     return binder::Status::ok();
254 }
255 
commitGsiChunkFromStream(const android::os::ParcelFileDescriptor & stream,int64_t bytes,bool * _aidl_return)256 binder::Status GsiService::commitGsiChunkFromStream(const android::os::ParcelFileDescriptor& stream,
257                                                     int64_t bytes, bool* _aidl_return) {
258     ENFORCE_SYSTEM;
259     std::lock_guard<std::mutex> guard(lock_);
260 
261     if (!installer_) {
262         *_aidl_return = false;
263         return binder::Status::ok();
264     }
265 
266     *_aidl_return = installer_->CommitGsiChunk(stream.get(), bytes);
267     return binder::Status::ok();
268 }
269 
StartAsyncOperation(const std::string & step,int64_t total_bytes)270 void GsiService::StartAsyncOperation(const std::string& step, int64_t total_bytes) {
271     std::lock_guard<std::mutex> guard(progress_lock_);
272 
273     progress_.step = step;
274     progress_.status = STATUS_WORKING;
275     progress_.bytes_processed = 0;
276     progress_.total_bytes = total_bytes;
277 }
278 
UpdateProgress(int status,int64_t bytes_processed)279 void GsiService::UpdateProgress(int status, int64_t bytes_processed) {
280     std::lock_guard<std::mutex> guard(progress_lock_);
281 
282     progress_.status = status;
283     if (status == STATUS_COMPLETE) {
284         progress_.bytes_processed = progress_.total_bytes;
285     } else {
286         progress_.bytes_processed = bytes_processed;
287     }
288 }
289 
getInstallProgress(::android::gsi::GsiProgress * _aidl_return)290 binder::Status GsiService::getInstallProgress(::android::gsi::GsiProgress* _aidl_return) {
291     ENFORCE_SYSTEM;
292     std::lock_guard<std::mutex> guard(progress_lock_);
293 
294     if (installer_ == nullptr) {
295         progress_ = {};
296     }
297     *_aidl_return = progress_;
298     return binder::Status::ok();
299 }
300 
commitGsiChunkFromAshmem(int64_t bytes,bool * _aidl_return)301 binder::Status GsiService::commitGsiChunkFromAshmem(int64_t bytes, bool* _aidl_return) {
302     ENFORCE_SYSTEM;
303     std::lock_guard<std::mutex> guard(lock_);
304 
305     if (!installer_) {
306         *_aidl_return = false;
307         return binder::Status::ok();
308     }
309     *_aidl_return = installer_->CommitGsiChunk(bytes);
310     return binder::Status::ok();
311 }
312 
setGsiAshmem(const::android::os::ParcelFileDescriptor & ashmem,int64_t size,bool * _aidl_return)313 binder::Status GsiService::setGsiAshmem(const ::android::os::ParcelFileDescriptor& ashmem,
314                                         int64_t size, bool* _aidl_return) {
315     ENFORCE_SYSTEM;
316     if (!installer_) {
317         *_aidl_return = false;
318         return binder::Status::ok();
319     }
320     *_aidl_return = installer_->MapAshmem(ashmem.get(), size);
321     return binder::Status::ok();
322 }
323 
enableGsiAsync(bool one_shot,const std::string & dsuSlot,const sp<IGsiServiceCallback> & resultCallback)324 binder::Status GsiService::enableGsiAsync(bool one_shot, const std::string& dsuSlot,
325                                           const sp<IGsiServiceCallback>& resultCallback) {
326     ENFORCE_SYSTEM_OR_SHELL_IF_UNLOCK;
327     std::lock_guard<std::mutex> guard(lock_);
328 
329     const auto result = EnableGsi(one_shot, dsuSlot);
330     resultCallback->onResult(result);
331     return binder::Status::ok();
332 }
333 
enableGsi(bool one_shot,const std::string & dsuSlot,int * _aidl_return)334 binder::Status GsiService::enableGsi(bool one_shot, const std::string& dsuSlot, int* _aidl_return) {
335     ENFORCE_SYSTEM_OR_SHELL_IF_UNLOCK;
336     std::lock_guard<std::mutex> guard(lock_);
337 
338     *_aidl_return = EnableGsi(one_shot, dsuSlot);
339     return binder::Status::ok();
340 }
341 
isGsiEnabled(bool * _aidl_return)342 binder::Status GsiService::isGsiEnabled(bool* _aidl_return) {
343     ENFORCE_SYSTEM_OR_SHELL;
344     std::lock_guard<std::mutex> guard(lock_);
345     std::string boot_key;
346     if (!GetInstallStatus(&boot_key)) {
347         *_aidl_return = false;
348     } else {
349         *_aidl_return = (boot_key != kInstallStatusDisabled);
350     }
351     return binder::Status::ok();
352 }
353 
removeGsiAsync(const sp<IGsiServiceCallback> & resultCallback)354 binder::Status GsiService::removeGsiAsync(const sp<IGsiServiceCallback>& resultCallback) {
355     int result = IGsiService::INSTALL_OK;
356     bool success = true;
357     auto status = removeGsi(&success);
358     if (!status.isOk() || !success) {
359         LOG(ERROR) << "Could not removeGsi: " << status.exceptionMessage().c_str();
360         result = IGsiService::INSTALL_ERROR_GENERIC;
361     }
362     resultCallback->onResult(result);
363     return binder::Status::ok();
364 }
365 
removeGsi(bool * _aidl_return)366 binder::Status GsiService::removeGsi(bool* _aidl_return) {
367     ENFORCE_SYSTEM_OR_SHELL_IF_UNLOCK;
368     std::lock_guard<std::mutex> guard(lock_);
369 
370     std::string install_dir = GetActiveInstalledImageDir();
371     if (IsGsiRunning()) {
372         // Can't remove gsi files while running.
373         *_aidl_return = UninstallGsi();
374     } else {
375         installer_ = {};
376         *_aidl_return = RemoveGsiFiles(install_dir);
377     }
378     return binder::Status::ok();
379 }
380 
disableGsi(bool * _aidl_return)381 binder::Status GsiService::disableGsi(bool* _aidl_return) {
382     ENFORCE_SYSTEM_OR_SHELL_IF_UNLOCK;
383     std::lock_guard<std::mutex> guard(lock_);
384 
385     *_aidl_return = DisableGsiInstall();
386     return binder::Status::ok();
387 }
388 
isGsiRunning(bool * _aidl_return)389 binder::Status GsiService::isGsiRunning(bool* _aidl_return) {
390     ENFORCE_SYSTEM_OR_SHELL;
391     std::lock_guard<std::mutex> guard(lock_);
392 
393     *_aidl_return = IsGsiRunning();
394     return binder::Status::ok();
395 }
396 
isGsiInstalled(bool * _aidl_return)397 binder::Status GsiService::isGsiInstalled(bool* _aidl_return) {
398     ENFORCE_SYSTEM_OR_SHELL;
399     std::lock_guard<std::mutex> guard(lock_);
400 
401     *_aidl_return = IsGsiInstalled();
402     return binder::Status::ok();
403 }
404 
isGsiInstallInProgress(bool * _aidl_return)405 binder::Status GsiService::isGsiInstallInProgress(bool* _aidl_return) {
406     ENFORCE_SYSTEM_OR_SHELL;
407     std::lock_guard<std::mutex> guard(lock_);
408 
409     *_aidl_return = !!installer_;
410     return binder::Status::ok();
411 }
412 
cancelGsiInstall(bool * _aidl_return)413 binder::Status GsiService::cancelGsiInstall(bool* _aidl_return) {
414     ENFORCE_SYSTEM;
415     should_abort_ = true;
416     std::lock_guard<std::mutex> guard(lock_);
417 
418     should_abort_ = false;
419     installer_ = nullptr;
420 
421     *_aidl_return = true;
422     return binder::Status::ok();
423 }
424 
getInstalledGsiImageDir(std::string * _aidl_return)425 binder::Status GsiService::getInstalledGsiImageDir(std::string* _aidl_return) {
426     ENFORCE_SYSTEM;
427     std::lock_guard<std::mutex> guard(lock_);
428 
429     *_aidl_return = GetActiveInstalledImageDir();
430     return binder::Status::ok();
431 }
432 
getActiveDsuSlot(std::string * _aidl_return)433 binder::Status GsiService::getActiveDsuSlot(std::string* _aidl_return) {
434     ENFORCE_SYSTEM_OR_SHELL;
435     std::lock_guard<std::mutex> guard(lock_);
436 
437     *_aidl_return = GetActiveDsuSlot();
438     return binder::Status::ok();
439 }
440 
getInstalledDsuSlots(std::vector<std::string> * _aidl_return)441 binder::Status GsiService::getInstalledDsuSlots(std::vector<std::string>* _aidl_return) {
442     ENFORCE_SYSTEM;
443     std::lock_guard<std::mutex> guard(lock_);
444     *_aidl_return = GetInstalledDsuSlots();
445     return binder::Status::ok();
446 }
447 
zeroPartition(const std::string & name,int * _aidl_return)448 binder::Status GsiService::zeroPartition(const std::string& name, int* _aidl_return) {
449     ENFORCE_SYSTEM_OR_SHELL_IF_UNLOCK;
450     std::lock_guard<std::mutex> guard(lock_);
451 
452     if (IsGsiRunning() || !IsGsiInstalled()) {
453         *_aidl_return = IGsiService::INSTALL_ERROR_GENERIC;
454         return binder::Status::ok();
455     }
456 
457     std::string install_dir = GetActiveInstalledImageDir();
458     *_aidl_return = PartitionInstaller::WipeWritable(GetDsuSlot(install_dir), install_dir, name);
459 
460     return binder::Status::ok();
461 }
462 
BinderError(const std::string & message,FiemapStatus::ErrorCode status=FiemapStatus::ErrorCode::ERROR)463 static binder::Status BinderError(const std::string& message,
464                                   FiemapStatus::ErrorCode status = FiemapStatus::ErrorCode::ERROR) {
465     return binder::Status::fromServiceSpecificError(static_cast<int32_t>(status), message.c_str());
466 }
467 
dumpDeviceMapperDevices(std::string * _aidl_return)468 binder::Status GsiService::dumpDeviceMapperDevices(std::string* _aidl_return) {
469     ENFORCE_SYSTEM_OR_SHELL;
470 
471     auto& dm = DeviceMapper::Instance();
472 
473     std::vector<DeviceMapper::DmBlockDevice> devices;
474     if (!dm.GetAvailableDevices(&devices)) {
475         return BinderError("Could not list devices");
476     }
477 
478     std::stringstream text;
479     for (const auto& device : devices) {
480         text << "Device " << device.name() << " (" << device.Major() << ":" << device.Minor()
481              << ")\n";
482 
483         std::vector<DeviceMapper::TargetInfo> table;
484         if (!dm.GetTableInfo(device.name(), &table)) {
485             continue;
486         }
487 
488         for (const auto& target : table) {
489             const auto& spec = target.spec;
490             auto target_type = DeviceMapper::GetTargetType(spec);
491             text << "    " << target_type << " " << spec.sector_start << " " << spec.length << " "
492                  << target.data << "\n";
493         }
494     }
495 
496     *_aidl_return = text.str();
497     return binder::Status::ok();
498 }
499 
getAvbPublicKey(AvbPublicKey * dst,int32_t * _aidl_return)500 binder::Status GsiService::getAvbPublicKey(AvbPublicKey* dst, int32_t* _aidl_return) {
501     ENFORCE_SYSTEM;
502     std::lock_guard<std::mutex> guard(lock_);
503 
504     if (!installer_) {
505         *_aidl_return = INSTALL_ERROR_GENERIC;
506         return binder::Status::ok();
507     }
508     int fd = installer_->GetPartitionFd();
509     if (fd == -1) {
510         LOG(ERROR) << "Failed to get partition fd";
511         *_aidl_return = INSTALL_ERROR_GENERIC;
512         return binder::Status::ok();
513     }
514 
515     if (!GetAvbPublicKeyFromFd(fd, dst)) {
516         LOG(ERROR) << "Failed to extract AVB public key";
517         *_aidl_return = INSTALL_ERROR_GENERIC;
518         return binder::Status::ok();
519     }
520     *_aidl_return = INSTALL_OK;
521     return binder::Status::ok();
522 }
523 
suggestScratchSize(int64_t * _aidl_return)524 binder::Status GsiService::suggestScratchSize(int64_t* _aidl_return) {
525     ENFORCE_SYSTEM;
526 
527     static constexpr uint64_t kMinScratchSize = 512_MiB;
528     static constexpr uint64_t kMaxScratchSize = 2_GiB;
529 
530     uint64_t size = 0;
531     struct statvfs info;
532     if (statvfs(install_dir_.c_str(), &info)) {
533         PLOG(ERROR) << "Could not statvfs(" << install_dir_ << ")";
534     } else {
535         uint64_t free_space = static_cast<uint64_t>(info.f_bavail) * info.f_frsize;
536         const auto free_space_threshold =
537                 PartitionInstaller::GetMinimumFreeSpaceThreshold(install_dir_);
538         if (free_space_threshold.has_value() && free_space > *free_space_threshold) {
539             // Round down to multiples of filesystem block size.
540             size = (free_space - *free_space_threshold) / info.f_frsize * info.f_frsize;
541         }
542     }
543 
544     // We can safely downcast the result here, since we clamped the result within int64_t range.
545     *_aidl_return = std::clamp(size, kMinScratchSize, kMaxScratchSize);
546     return binder::Status::ok();
547 }
548 
ResetBootAttemptCounter()549 bool GsiService::ResetBootAttemptCounter() {
550     if (!android::base::WriteStringToFile("0", kDsuInstallStatusFile)) {
551         PLOG(ERROR) << "write " << kDsuInstallStatusFile;
552         return false;
553     }
554     SetProperty(kGsiInstalledProp, "1");
555     return true;
556 }
557 
SetBootMode(bool one_shot)558 bool GsiService::SetBootMode(bool one_shot) {
559     if (one_shot) {
560         if (!android::base::WriteStringToFile("1", kDsuOneShotBootFile)) {
561             PLOG(ERROR) << "write " << kDsuOneShotBootFile;
562             return false;
563         }
564     } else if (!access(kDsuOneShotBootFile, F_OK)) {
565         std::string error;
566         if (!android::base::RemoveFileIfExists(kDsuOneShotBootFile, &error)) {
567             LOG(ERROR) << error;
568             return false;
569         }
570     }
571     return true;
572 }
573 
UidSecurityError()574 static binder::Status UidSecurityError() {
575     uid_t uid = IPCThreadState::self()->getCallingUid();
576     auto message = StringPrintf("UID %d is not allowed", uid);
577     return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, String8(message.c_str()));
578 }
579 
580 class ImageService : public BinderService<ImageService>, public BnImageService {
581   public:
582     ImageService(GsiService* service, std::unique_ptr<ImageManager>&& impl, uid_t uid);
583     binder::Status getAllBackingImages(std::vector<std::string>* _aidl_return);
584     binder::Status createBackingImage(const std::string& name, int64_t size, int flags,
585                                       const sp<IProgressCallback>& on_progress) override;
586     binder::Status deleteBackingImage(const std::string& name) override;
587     binder::Status mapImageDevice(const std::string& name, int32_t timeout_ms,
588                                   MappedImage* mapping) override;
589     binder::Status unmapImageDevice(const std::string& name) override;
590     binder::Status backingImageExists(const std::string& name, bool* _aidl_return) override;
591     binder::Status isImageMapped(const std::string& name, bool* _aidl_return) override;
592     binder::Status getAvbPublicKey(const std::string& name, AvbPublicKey* dst,
593                                    int32_t* _aidl_return) override;
594     binder::Status zeroFillNewImage(const std::string& name, int64_t bytes) override;
595     binder::Status removeAllImages() override;
596     binder::Status disableImage(const std::string& name) override;
597     binder::Status removeDisabledImages() override;
598     binder::Status getMappedImageDevice(const std::string& name, std::string* device) override;
599     binder::Status isImageDisabled(const std::string& name, bool* _aidl_return) override;
600 
601   private:
602     bool CheckUid();
603 
604     android::sp<GsiService> service_;
605     std::unique_ptr<ImageManager> impl_;
606     uid_t uid_;
607 };
608 
ImageService(GsiService * service,std::unique_ptr<ImageManager> && impl,uid_t uid)609 ImageService::ImageService(GsiService* service, std::unique_ptr<ImageManager>&& impl, uid_t uid)
610     : service_(service), impl_(std::move(impl)), uid_(uid) {}
611 
getAllBackingImages(std::vector<std::string> * _aidl_return)612 binder::Status ImageService::getAllBackingImages(std::vector<std::string>* _aidl_return) {
613     *_aidl_return = impl_->GetAllBackingImages();
614     return binder::Status::ok();
615 }
616 
createBackingImage(const std::string & name,int64_t size,int flags,const sp<IProgressCallback> & on_progress)617 binder::Status ImageService::createBackingImage(const std::string& name, int64_t size, int flags,
618                                                 const sp<IProgressCallback>& on_progress) {
619     if (!CheckUid()) return UidSecurityError();
620 
621     std::lock_guard<std::mutex> guard(service_->lock());
622 
623     std::function<bool(uint64_t, uint64_t)> callback;
624     if (on_progress) {
625         callback = [on_progress](uint64_t current, uint64_t total) -> bool {
626             auto status = on_progress->onProgress(static_cast<int64_t>(current),
627                                                   static_cast<int64_t>(total));
628             if (!status.isOk()) {
629                 LOG(ERROR) << "progress callback returned: " << status.toString8().c_str();
630                 return false;
631             }
632             return true;
633         };
634     }
635 
636     auto res = impl_->CreateBackingImage(name, size, flags, std::move(callback));
637     if (!res.is_ok()) {
638         return BinderError("Failed to create: " + res.string(), res.error_code());
639     }
640     return binder::Status::ok();
641 }
642 
deleteBackingImage(const std::string & name)643 binder::Status ImageService::deleteBackingImage(const std::string& name) {
644     if (!CheckUid()) return UidSecurityError();
645 
646     std::lock_guard<std::mutex> guard(service_->lock());
647 
648     if (!impl_->DeleteBackingImage(name)) {
649         return BinderError("Failed to delete");
650     }
651     return binder::Status::ok();
652 }
653 
mapImageDevice(const std::string & name,int32_t timeout_ms,MappedImage * mapping)654 binder::Status ImageService::mapImageDevice(const std::string& name, int32_t timeout_ms,
655                                             MappedImage* mapping) {
656     if (!CheckUid()) return UidSecurityError();
657 
658     std::lock_guard<std::mutex> guard(service_->lock());
659 
660     if (!impl_->MapImageDevice(name, std::chrono::milliseconds(timeout_ms), &mapping->path)) {
661         return BinderError("Failed to map");
662     }
663     return binder::Status::ok();
664 }
665 
unmapImageDevice(const std::string & name)666 binder::Status ImageService::unmapImageDevice(const std::string& name) {
667     if (!CheckUid()) return UidSecurityError();
668 
669     std::lock_guard<std::mutex> guard(service_->lock());
670 
671     if (!impl_->UnmapImageDevice(name)) {
672         return BinderError("Failed to unmap");
673     }
674     return binder::Status::ok();
675 }
676 
backingImageExists(const std::string & name,bool * _aidl_return)677 binder::Status ImageService::backingImageExists(const std::string& name, bool* _aidl_return) {
678     if (!CheckUid()) return UidSecurityError();
679 
680     std::lock_guard<std::mutex> guard(service_->lock());
681 
682     *_aidl_return = impl_->BackingImageExists(name);
683     return binder::Status::ok();
684 }
685 
isImageMapped(const std::string & name,bool * _aidl_return)686 binder::Status ImageService::isImageMapped(const std::string& name, bool* _aidl_return) {
687     if (!CheckUid()) return UidSecurityError();
688 
689     std::lock_guard<std::mutex> guard(service_->lock());
690 
691     *_aidl_return = impl_->IsImageMapped(name);
692     return binder::Status::ok();
693 }
694 
getAvbPublicKey(const std::string & name,AvbPublicKey * dst,int32_t * _aidl_return)695 binder::Status ImageService::getAvbPublicKey(const std::string& name, AvbPublicKey* dst,
696                                              int32_t* _aidl_return) {
697     if (!CheckUid()) return UidSecurityError();
698 
699     std::lock_guard<std::mutex> guard(service_->lock());
700 
701     std::string device_path;
702     std::unique_ptr<MappedDevice> mapped_device;
703     if (!impl_->IsImageMapped(name)) {
704         mapped_device = MappedDevice::Open(impl_.get(), 10s, name);
705         if (!mapped_device) {
706             PLOG(ERROR) << "Fail to map image: " << name;
707             *_aidl_return = IMAGE_ERROR;
708             return binder::Status::ok();
709         }
710         device_path = mapped_device->path();
711     } else {
712         if (!impl_->GetMappedImageDevice(name, &device_path)) {
713             PLOG(ERROR) << "GetMappedImageDevice() failed";
714             *_aidl_return = IMAGE_ERROR;
715             return binder::Status::ok();
716         }
717     }
718     android::base::unique_fd fd(open(device_path.c_str(), O_RDONLY | O_CLOEXEC));
719     if (!fd.ok()) {
720         PLOG(ERROR) << "Fail to open mapped device: " << device_path;
721         *_aidl_return = IMAGE_ERROR;
722         return binder::Status::ok();
723     }
724     bool ok = GetAvbPublicKeyFromFd(fd.get(), dst);
725     fd = {};
726     if (!ok) {
727         LOG(ERROR) << "Failed to extract AVB public key";
728         *_aidl_return = IMAGE_ERROR;
729         return binder::Status::ok();
730     }
731     *_aidl_return = IMAGE_OK;
732     return binder::Status::ok();
733 }
734 
zeroFillNewImage(const std::string & name,int64_t bytes)735 binder::Status ImageService::zeroFillNewImage(const std::string& name, int64_t bytes) {
736     if (!CheckUid()) return UidSecurityError();
737 
738     std::lock_guard<std::mutex> guard(service_->lock());
739 
740     if (bytes < 0) {
741         return BinderError("Cannot use negative values");
742     }
743     auto res = impl_->ZeroFillNewImage(name, bytes);
744     if (!res.is_ok()) {
745         return BinderError("Failed to fill image with zeros: " + res.string(), res.error_code());
746     }
747     return binder::Status::ok();
748 }
749 
removeAllImages()750 binder::Status ImageService::removeAllImages() {
751     if (!CheckUid()) return UidSecurityError();
752 
753     std::lock_guard<std::mutex> guard(service_->lock());
754     if (!impl_->RemoveAllImages()) {
755         return BinderError("Failed to remove all images");
756     }
757     return binder::Status::ok();
758 }
759 
disableImage(const std::string & name)760 binder::Status ImageService::disableImage(const std::string& name) {
761     if (!CheckUid()) return UidSecurityError();
762 
763     std::lock_guard<std::mutex> guard(service_->lock());
764     if (!impl_->DisableImage(name)) {
765         return BinderError("Failed to disable image: " + name);
766     }
767     return binder::Status::ok();
768 }
769 
removeDisabledImages()770 binder::Status ImageService::removeDisabledImages() {
771     if (!CheckUid()) return UidSecurityError();
772 
773     std::lock_guard<std::mutex> guard(service_->lock());
774     if (!impl_->RemoveDisabledImages()) {
775         return BinderError("Failed to remove disabled images");
776     }
777     return binder::Status::ok();
778 }
779 
isImageDisabled(const std::string & name,bool * _aidl_return)780 binder::Status ImageService::isImageDisabled(const std::string& name, bool* _aidl_return) {
781     if (!CheckUid()) return UidSecurityError();
782 
783     std::lock_guard<std::mutex> guard(service_->lock());
784     *_aidl_return = impl_->IsImageDisabled(name);
785     return binder::Status::ok();
786 }
787 
getMappedImageDevice(const std::string & name,std::string * device)788 binder::Status ImageService::getMappedImageDevice(const std::string& name, std::string* device) {
789     if (!CheckUid()) return UidSecurityError();
790 
791     std::lock_guard<std::mutex> guard(service_->lock());
792     if (!impl_->GetMappedImageDevice(name, device)) {
793         *device = "";
794     }
795     return binder::Status::ok();
796 }
797 
CheckUid()798 bool ImageService::CheckUid() {
799     return uid_ == IPCThreadState::self()->getCallingUid();
800 }
801 
openImageService(const std::string & prefix,android::sp<IImageService> * _aidl_return)802 binder::Status GsiService::openImageService(const std::string& prefix,
803                                             android::sp<IImageService>* _aidl_return) {
804     using android::base::StartsWith;
805 
806     static constexpr char kImageMetadataPrefix[] = "/metadata/gsi/";
807     static constexpr char kImageDataPrefix[] = "/data/gsi/";
808 
809     auto in_metadata_dir = kImageMetadataPrefix + prefix;
810     auto in_data_dir = kImageDataPrefix + prefix;
811     auto install_dir_file = DsuInstallDirFile(GetDsuSlot(prefix));
812 
813     std::string in_data_dir_tmp;
814     if (android::base::ReadFileToString(install_dir_file, &in_data_dir_tmp)) {
815         in_data_dir = in_data_dir_tmp;
816         LOG(INFO) << "load " << install_dir_file << ":" << in_data_dir;
817     }
818     std::string metadata_dir, data_dir;
819     if (!android::base::Realpath(in_metadata_dir, &metadata_dir)) {
820         PLOG(ERROR) << "realpath failed for metadata: " << in_metadata_dir;
821         return BinderError("Invalid path");
822     }
823     if (!android::base::Realpath(in_data_dir, &data_dir)) {
824         PLOG(ERROR) << "realpath failed for data: " << in_data_dir;
825         return BinderError("Invalid path");
826     }
827     if (!StartsWith(metadata_dir, kImageMetadataPrefix)) {
828         return BinderError("Invalid metadata path");
829     }
830     if (!StartsWith(data_dir, kImageDataPrefix) && !StartsWith(data_dir, kDsuSDPrefix)) {
831         return BinderError("Invalid data path");
832     }
833 
834     uid_t uid = IPCThreadState::self()->getCallingUid();
835     if (uid != AID_ROOT) {
836         return UidSecurityError();
837     }
838 
839     auto impl = ImageManager::Open(metadata_dir, data_dir);
840     if (!impl) {
841         return BinderError("Unknown error");
842     }
843 
844     *_aidl_return = new ImageService(this, std::move(impl), uid);
845     return binder::Status::ok();
846 }
847 
CheckUid(AccessLevel level)848 binder::Status GsiService::CheckUid(AccessLevel level) {
849     std::vector<uid_t> allowed_uids{AID_ROOT, AID_SYSTEM};
850     if (level == AccessLevel::SystemOrShell) {
851         allowed_uids.push_back(AID_SHELL);
852     }
853 
854     uid_t uid = IPCThreadState::self()->getCallingUid();
855     for (const auto& allowed_uid : allowed_uids) {
856         if (allowed_uid == uid) {
857             return binder::Status::ok();
858         }
859     }
860     return UidSecurityError();
861 }
862 
IsExternalStoragePath(const std::string & path)863 static bool IsExternalStoragePath(const std::string& path) {
864     if (!android::base::StartsWith(path, kDsuSDPrefix)) {
865         return false;
866     }
867     unique_fd fd(open(path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
868     if (fd < 0) {
869         PLOG(ERROR) << "open failed: " << path;
870         return false;
871     }
872     struct statfs info;
873     if (fstatfs(fd, &info)) {
874         PLOG(ERROR) << "statfs failed: " << path;
875         return false;
876     }
877     LOG(ERROR) << "fs type: " << info.f_type;
878     return info.f_type == MSDOS_SUPER_MAGIC;
879 }
880 
ValidateInstallParams(std::string & install_dir)881 int GsiService::ValidateInstallParams(std::string& install_dir) {
882     // If no install path was specified, use the default path. We also allow
883     // specifying the top-level folder, and then we choose the correct location
884     // underneath.
885     if (install_dir.empty() || install_dir == "/data/gsi") {
886         install_dir = kDefaultDsuImageFolder;
887     }
888 
889     if (access(install_dir.c_str(), F_OK) != 0 && (errno == ENOENT)) {
890         if (android::base::StartsWith(install_dir, kDsuSDPrefix) ||
891             android::base::StartsWith(install_dir, kDefaultDsuImageFolder)) {
892             if (mkdir(install_dir.c_str(), 0755) != 0) {
893                 PLOG(ERROR) << "Failed to create " << install_dir;
894                 return INSTALL_ERROR_GENERIC;
895             }
896         }
897     }
898     // Normalize the path and add a trailing slash.
899     std::string origInstallDir = install_dir;
900     if (!android::base::Realpath(origInstallDir, &install_dir)) {
901         PLOG(ERROR) << "realpath failed: " << origInstallDir;
902         return INSTALL_ERROR_GENERIC;
903     }
904     // Ensure the path ends in / for consistency.
905     if (!android::base::EndsWith(install_dir, "/")) {
906         install_dir += "/";
907     }
908 
909     // Currently, we can only install to /data/gsi/ or external storage.
910     if (IsExternalStoragePath(install_dir)) {
911         Fstab fstab;
912         if (!ReadDefaultFstab(&fstab)) {
913             LOG(ERROR) << "cannot read default fstab";
914             return INSTALL_ERROR_GENERIC;
915         }
916         FstabEntry* system = GetEntryForMountPoint(&fstab, "/system");
917         if (!system) {
918             LOG(ERROR) << "cannot find /system fstab entry";
919             return INSTALL_ERROR_GENERIC;
920         }
921         if (fs_mgr_verity_is_check_at_most_once(*system)) {
922             LOG(ERROR) << "cannot install GSIs to external media if verity uses check_at_most_once";
923             return INSTALL_ERROR_GENERIC;
924         }
925     } else if (!android::base::StartsWith(install_dir, kDefaultDsuImageFolder)) {
926         LOG(ERROR) << "cannot install DSU to " << install_dir;
927         return INSTALL_ERROR_GENERIC;
928     }
929     return INSTALL_OK;
930 }
931 
GetActiveDsuSlot()932 std::string GsiService::GetActiveDsuSlot() {
933     if (!install_dir_.empty()) {
934         return GetDsuSlot(install_dir_);
935     } else {
936         std::string active_dsu;
937         return GetActiveDsu(&active_dsu) ? active_dsu : "";
938     }
939 }
940 
GetActiveInstalledImageDir()941 std::string GsiService::GetActiveInstalledImageDir() {
942     // Just in case an install was left hanging.
943     if (installer_) {
944         return installer_->install_dir();
945     } else {
946         return GetInstalledImageDir();
947     }
948 }
949 
GetInstalledImageDir()950 std::string GsiService::GetInstalledImageDir() {
951     // If there's no install left, just return /data/gsi since that's where
952     // installs go by default.
953     std::string active_dsu;
954     std::string dir;
955     if (GetActiveDsu(&active_dsu) &&
956         android::base::ReadFileToString(DsuInstallDirFile(active_dsu), &dir)) {
957         return dir;
958     }
959     return kDefaultDsuImageFolder;
960 }
961 
GetVoldService()962 static android::sp<android::os::IVold> GetVoldService() {
963     return android::waitForService<android::os::IVold>(android::String16("vold"));
964 }
965 
RemoveGsiFiles(const std::string & install_dir)966 bool GsiService::RemoveGsiFiles(const std::string& install_dir) {
967     bool ok = true;
968     auto active_dsu = GetDsuSlot(install_dir);
969     if (auto manager = ImageManager::Open(MetadataDir(active_dsu), install_dir)) {
970         std::vector<std::string> images = manager->GetAllBackingImages();
971         for (auto&& image : images) {
972             if (!android::base::EndsWith(image, kDsuPostfix)) {
973                 continue;
974             }
975             if (manager->IsImageMapped(image)) {
976                 ok &= manager->UnmapImageDevice(image);
977             }
978             ok &= manager->DeleteBackingImage(image);
979         }
980     }
981     auto dsu_slot = GetDsuSlot(install_dir);
982     std::vector<std::string> files{
983             kDsuInstallStatusFile,
984             kDsuOneShotBootFile,
985             DsuInstallDirFile(dsu_slot),
986             GetCompleteIndication(dsu_slot),
987     };
988     for (const auto& file : files) {
989         std::string message;
990         if (!RemoveFileIfExists(file, &message)) {
991             LOG(ERROR) << message;
992             ok = false;
993         }
994     }
995     if (auto vold = GetVoldService()) {
996         auto status = vold->destroyDsuMetadataKey(dsu_slot);
997         if (status.isOk()) {
998             std::string message;
999             if (!RemoveFileIfExists(DsuMetadataKeyDirFile(dsu_slot), &message)) {
1000                 LOG(ERROR) << message;
1001                 ok = false;
1002             }
1003         } else {
1004             LOG(ERROR) << "Failed to destroy DSU metadata encryption key.";
1005             ok = false;
1006         }
1007     } else {
1008         LOG(ERROR) << "Failed to retrieve vold service.";
1009         ok = false;
1010     }
1011     if (ok) {
1012         SetProperty(kGsiInstalledProp, "0");
1013     }
1014     return ok;
1015 }
1016 
EnableGsi(bool one_shot,const std::string & dsu_slot)1017 int GsiService::EnableGsi(bool one_shot, const std::string& dsu_slot) {
1018     if (!android::gsi::IsGsiInstalled()) {
1019         LOG(ERROR) << "no gsi installed - cannot enable";
1020         return IGsiService::INSTALL_ERROR_GENERIC;
1021     }
1022     if (installer_) {
1023         LOG(ERROR) << "cannot enable an ongoing installation, was closeInstall() called?";
1024         return IGsiService::INSTALL_ERROR_GENERIC;
1025     }
1026 
1027     if (!DisableGsi()) {
1028         PLOG(ERROR) << "cannot write DSU status file";
1029         return IGsiService::INSTALL_ERROR_GENERIC;
1030     }
1031     if (!SetBootMode(one_shot)) {
1032         return IGsiService::INSTALL_ERROR_GENERIC;
1033     }
1034     if (!ResetBootAttemptCounter()) {
1035         return IGsiService::INSTALL_ERROR_GENERIC;
1036     }
1037 
1038     if (!WriteStringToFile(dsu_slot, kDsuActiveFile)) {
1039         PLOG(ERROR) << "cannot write active DSU slot (" << dsu_slot << "): " << kDsuActiveFile;
1040         return IGsiService::INSTALL_ERROR_GENERIC;
1041     }
1042     RestoreconMetadataFiles();
1043     return IGsiService::INSTALL_OK;
1044 }
1045 
DisableGsiInstall()1046 bool GsiService::DisableGsiInstall() {
1047     if (!android::gsi::IsGsiInstalled()) {
1048         LOG(ERROR) << "cannot disable gsi install - no install detected";
1049         return false;
1050     }
1051     if (installer_) {
1052         LOG(ERROR) << "cannot disable gsi during GSI installation";
1053         return false;
1054     }
1055     if (!DisableGsi()) {
1056         PLOG(ERROR) << "could not write gsi status";
1057         return false;
1058     }
1059     return true;
1060 }
1061 
GetCompleteIndication(const std::string & dsu_slot)1062 std::string GsiService::GetCompleteIndication(const std::string& dsu_slot) {
1063     return DSU_METADATA_PREFIX + dsu_slot + "/complete";
1064 }
1065 
IsInstallationComplete(const std::string & dsu_slot)1066 bool GsiService::IsInstallationComplete(const std::string& dsu_slot) {
1067     if (access(kDsuInstallStatusFile, F_OK) != 0) {
1068         return false;
1069     }
1070     std::string file = GetCompleteIndication(dsu_slot);
1071     std::string content;
1072     if (!ReadFileToString(file, &content)) {
1073         return false;
1074     }
1075     return content == "OK";
1076 }
1077 
GetInstalledDsuSlots()1078 std::vector<std::string> GsiService::GetInstalledDsuSlots() {
1079     std::vector<std::string> dsu_slots;
1080     auto d = std::unique_ptr<DIR, decltype(&closedir)>(opendir(DSU_METADATA_PREFIX), closedir);
1081     if (d != nullptr) {
1082         struct dirent* de;
1083         while ((de = readdir(d.get())) != nullptr) {
1084             if (de->d_name[0] == '.') {
1085                 continue;
1086             }
1087             auto dsu_slot = std::string(de->d_name);
1088             if (access(DsuInstallDirFile(dsu_slot).c_str(), F_OK) != 0) {
1089                 continue;
1090             }
1091             dsu_slots.push_back(dsu_slot);
1092         }
1093     }
1094     return dsu_slots;
1095 }
1096 
CleanCorruptedInstallation()1097 void GsiService::CleanCorruptedInstallation() {
1098     for (auto&& slot : GetInstalledDsuSlots()) {
1099         bool is_complete = IsInstallationComplete(slot);
1100         if (!is_complete) {
1101             LOG(INFO) << "CleanCorruptedInstallation for slot: " << slot;
1102             std::string install_dir;
1103             if (!android::base::ReadFileToString(DsuInstallDirFile(slot), &install_dir) ||
1104                 !RemoveGsiFiles(install_dir)) {
1105                 LOG(ERROR) << "Failed to CleanCorruptedInstallation on " << slot;
1106             }
1107         }
1108     }
1109 }
1110 
RunStartupTasks()1111 void GsiService::RunStartupTasks() {
1112     CleanCorruptedInstallation();
1113 
1114     std::string active_dsu;
1115     if (!GetActiveDsu(&active_dsu)) {
1116         PLOG(INFO) << "no DSU";
1117         return;
1118     }
1119     std::string boot_key;
1120     if (!GetInstallStatus(&boot_key)) {
1121         PLOG(ERROR) << "read " << kDsuInstallStatusFile;
1122         return;
1123     }
1124 
1125     if (!IsGsiRunning()) {
1126         // Check if a wipe was requested from fastboot or adb-in-gsi.
1127         if (boot_key == kInstallStatusWipe) {
1128             RemoveGsiFiles(GetInstalledImageDir());
1129         }
1130     } else {
1131         // NB: When single-boot is enabled, init will write "disabled" into the
1132         // install_status file, which will cause GetBootAttempts to return
1133         // false. Thus, we won't write "ok" here.
1134         int ignore;
1135         if (GetBootAttempts(boot_key, &ignore)) {
1136             // Mark the GSI as having successfully booted.
1137             if (!android::base::WriteStringToFile(kInstallStatusOk, kDsuInstallStatusFile)) {
1138                 PLOG(ERROR) << "write " << kDsuInstallStatusFile;
1139             }
1140         }
1141     }
1142 }
1143 
VerifyImageMaps()1144 void GsiService::VerifyImageMaps() {
1145     std::vector<std::pair<std::string, std::string>> paths = {
1146             {"/metadata/gsi/remount", "/data/gsi/remount"},
1147             {"/metadata/gsi/ota", "/data/gsi/ota"},
1148     };
1149 
1150     for (const auto& [metadata_dir, data_dir] : paths) {
1151         auto impl = ImageManager::Open(metadata_dir, data_dir);
1152         if (!impl) {
1153             LOG(ERROR) << "Could not open ImageManager for " << metadata_dir << " and " << data_dir;
1154             continue;
1155         }
1156         if (!impl->ValidateImageMaps()) {
1157             LOG(ERROR) << "ImageManager for " << metadata_dir
1158                        << " failed validation, device data is at risk. Rebooting.";
1159             android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,fastboot");
1160             continue;
1161         }
1162         LOG(INFO) << "ImageManager verification passed for " << metadata_dir;
1163     }
1164 }
1165 
GetAvbPublicKeyFromFd(int fd,AvbPublicKey * dst)1166 static bool GetAvbPublicKeyFromFd(int fd, AvbPublicKey* dst) {
1167     // Read the AVB footer from EOF.
1168     int64_t total_size = get_block_device_size(fd);
1169     int64_t footer_offset = total_size - AVB_FOOTER_SIZE;
1170     std::array<uint8_t, AVB_FOOTER_SIZE> footer_bytes;
1171     if (!ReadFullyAtOffset(fd, footer_bytes.data(), AVB_FOOTER_SIZE, footer_offset)) {
1172         PLOG(ERROR) << "cannot read AVB footer";
1173         return false;
1174     }
1175     // Validate the AVB footer data and byte swap to native byte order.
1176     AvbFooter footer;
1177     if (!avb_footer_validate_and_byteswap((const AvbFooter*)footer_bytes.data(), &footer)) {
1178         LOG(ERROR) << "invalid AVB footer";
1179         return false;
1180     }
1181     // Read the VBMeta image.
1182     std::vector<uint8_t> vbmeta_bytes(footer.vbmeta_size);
1183     if (!ReadFullyAtOffset(fd, vbmeta_bytes.data(), vbmeta_bytes.size(), footer.vbmeta_offset)) {
1184         PLOG(ERROR) << "cannot read VBMeta image";
1185         return false;
1186     }
1187     // Validate the VBMeta image and retrieve AVB public key.
1188     // After a successful call to avb_vbmeta_image_verify(), public_key_data
1189     // will point to the serialized AVB public key, in the same format generated
1190     // by the `avbtool extract_public_key` command.
1191     const uint8_t* public_key_data;
1192     size_t public_key_size;
1193     AvbVBMetaVerifyResult result = avb_vbmeta_image_verify(vbmeta_bytes.data(), vbmeta_bytes.size(),
1194                                                            &public_key_data, &public_key_size);
1195     if (result != AVB_VBMETA_VERIFY_RESULT_OK) {
1196         LOG(ERROR) << "invalid VBMeta image: " << avb_vbmeta_verify_result_to_string(result);
1197         return false;
1198     }
1199     if (public_key_data != nullptr) {
1200         dst->bytes.resize(public_key_size);
1201         memcpy(dst->bytes.data(), public_key_data, public_key_size);
1202         dst->sha1.resize(SHA_DIGEST_LENGTH);
1203         SHA1(public_key_data, public_key_size, dst->sha1.data());
1204     }
1205     return true;
1206 }
1207 
1208 }  // namespace gsi
1209 }  // namespace android
1210