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