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