Loading cmds/dumpstate/DumpstateService.cpp +60 −42 Original line number Diff line number Diff line Loading @@ -18,8 +18,9 @@ #include "DumpstateService.h" #include <android-base/stringprintf.h> #include <memory> #include <android-base/stringprintf.h> #include "android/os/BnDumpstate.h" #include "DumpstateInternal.h" Loading Loading @@ -48,9 +49,10 @@ static binder::Status error(uint32_t code, const std::string& msg) { return binder::Status::fromServiceSpecificError(code, String8(msg.c_str())); } // Takes ownership of data. static void* callAndNotify(void* data) { DumpstateInfo& ds_info = *static_cast<DumpstateInfo*>(data); ds_info.ds->Run(ds_info.calling_uid, ds_info.calling_package); std::unique_ptr<DumpstateInfo> ds_info(static_cast<DumpstateInfo*>(data)); ds_info->ds->Run(ds_info->calling_uid, ds_info->calling_package); MYLOGD("Finished Run()\n"); return nullptr; } Loading @@ -59,7 +61,7 @@ class DumpstateToken : public BnDumpstateToken {}; } // namespace DumpstateService::DumpstateService() : ds_(Dumpstate::GetInstance()) { DumpstateService::DumpstateService() : ds_(nullptr) { } char const* DumpstateService::getServiceName() { Loading @@ -78,6 +80,8 @@ status_t DumpstateService::Start() { return android::OK; } // Note: this method is part of the old flow and is not expected to be used in combination // with startBugreport. binder::Status DumpstateService::setListener(const std::string& name, const sp<IDumpstateListener>& listener, bool getSectionDetails, Loading @@ -92,20 +96,22 @@ binder::Status DumpstateService::setListener(const std::string& name, return binder::Status::ok(); } std::lock_guard<std::mutex> lock(lock_); if (ds_.listener_ != nullptr) { MYLOGE("setListener(%s): already set (%s)\n", name.c_str(), ds_.listener_name_.c_str()); if (ds_ == nullptr) { ds_ = &(Dumpstate::GetInstance()); } if (ds_->listener_ != nullptr) { MYLOGE("setListener(%s): already set (%s)\n", name.c_str(), ds_->listener_name_.c_str()); return binder::Status::ok(); } ds_.listener_name_ = name; ds_.listener_ = listener; ds_.report_section_ = getSectionDetails; ds_->listener_name_ = name; ds_->listener_ = listener; ds_->report_section_ = getSectionDetails; *returned_token = new DumpstateToken(); return binder::Status::ok(); } // TODO(b/111441001): Hook up to consent service & copy final br only if user approves. binder::Status DumpstateService::startBugreport(int32_t calling_uid, const std::string& calling_package, const android::base::unique_fd& bugreport_fd, Loading Loading @@ -133,21 +139,29 @@ binder::Status DumpstateService::startBugreport(int32_t calling_uid, options->Initialize(static_cast<Dumpstate::BugreportMode>(bugreport_mode), bugreport_fd, screenshot_fd); // This is the bugreporting API flow, so ensure there is only one bugreport in progress at a // time. std::lock_guard<std::mutex> lock(lock_); // TODO(b/111441001): Disallow multiple simultaneous bugreports. ds_.SetOptions(std::move(options)); if (ds_ != nullptr) { return exception(binder::Status::EX_SERVICE_SPECIFIC, "There is already a bugreport in progress"); } ds_ = &(Dumpstate::GetInstance()); ds_->SetOptions(std::move(options)); if (listener != nullptr) { ds_.listener_ = listener; ds_->listener_ = listener; } DumpstateInfo ds_info; ds_info.ds = &ds_; ds_info.calling_uid = calling_uid; ds_info.calling_package = calling_package; DumpstateInfo* ds_info = new DumpstateInfo(); ds_info->ds = ds_; ds_info->calling_uid = calling_uid; ds_info->calling_package = calling_package; pthread_t thread; status_t err = pthread_create(&thread, nullptr, callAndNotify, &ds_); status_t err = pthread_create(&thread, nullptr, callAndNotify, ds_info); if (err != 0) { delete ds_info; ds_info = nullptr; return error(err, "Could not create a background thread."); } return binder::Status::ok(); Loading @@ -162,32 +176,36 @@ binder::Status DumpstateService::cancelBugreport() { } status_t DumpstateService::dump(int fd, const Vector<String16>&) { std::string destination = ds_.options_->bugreport_fd.get() != -1 ? StringPrintf("[fd:%d]", ds_.options_->bugreport_fd.get()) : ds_.bugreport_internal_dir_.c_str(); dprintf(fd, "id: %d\n", ds_.id_); dprintf(fd, "pid: %d\n", ds_.pid_); dprintf(fd, "update_progress: %s\n", ds_.options_->do_progress_updates ? "true" : "false"); dprintf(fd, "update_progress_threshold: %d\n", ds_.update_progress_threshold_); dprintf(fd, "last_updated_progress: %d\n", ds_.last_updated_progress_); if (ds_ == nullptr) { dprintf(fd, "Bugreport not in progress yet"); return NO_ERROR; } std::string destination = ds_->options_->bugreport_fd.get() != -1 ? StringPrintf("[fd:%d]", ds_->options_->bugreport_fd.get()) : ds_->bugreport_internal_dir_.c_str(); dprintf(fd, "id: %d\n", ds_->id_); dprintf(fd, "pid: %d\n", ds_->pid_); dprintf(fd, "update_progress: %s\n", ds_->options_->do_progress_updates ? "true" : "false"); dprintf(fd, "update_progress_threshold: %d\n", ds_->update_progress_threshold_); dprintf(fd, "last_updated_progress: %d\n", ds_->last_updated_progress_); dprintf(fd, "progress:\n"); ds_.progress_->Dump(fd, " "); dprintf(fd, "args: %s\n", ds_.options_->args.c_str()); dprintf(fd, "extra_options: %s\n", ds_.options_->extra_options.c_str()); dprintf(fd, "version: %s\n", ds_.version_.c_str()); ds_->progress_->Dump(fd, " "); dprintf(fd, "args: %s\n", ds_->options_->args.c_str()); dprintf(fd, "extra_options: %s\n", ds_->options_->extra_options.c_str()); dprintf(fd, "version: %s\n", ds_->version_.c_str()); dprintf(fd, "bugreport_dir: %s\n", destination.c_str()); dprintf(fd, "screenshot_path: %s\n", ds_.screenshot_path_.c_str()); dprintf(fd, "log_path: %s\n", ds_.log_path_.c_str()); dprintf(fd, "tmp_path: %s\n", ds_.tmp_path_.c_str()); dprintf(fd, "path: %s\n", ds_.path_.c_str()); dprintf(fd, "extra_options: %s\n", ds_.options_->extra_options.c_str()); dprintf(fd, "base_name: %s\n", ds_.base_name_.c_str()); dprintf(fd, "name: %s\n", ds_.name_.c_str()); dprintf(fd, "now: %ld\n", ds_.now_); dprintf(fd, "is_zipping: %s\n", ds_.IsZipping() ? "true" : "false"); dprintf(fd, "listener: %s\n", ds_.listener_name_.c_str()); dprintf(fd, "notification title: %s\n", ds_.options_->notification_title.c_str()); dprintf(fd, "notification description: %s\n", ds_.options_->notification_description.c_str()); dprintf(fd, "screenshot_path: %s\n", ds_->screenshot_path_.c_str()); dprintf(fd, "log_path: %s\n", ds_->log_path_.c_str()); dprintf(fd, "tmp_path: %s\n", ds_->tmp_path_.c_str()); dprintf(fd, "path: %s\n", ds_->path_.c_str()); dprintf(fd, "extra_options: %s\n", ds_->options_->extra_options.c_str()); dprintf(fd, "base_name: %s\n", ds_->base_name_.c_str()); dprintf(fd, "name: %s\n", ds_->name_.c_str()); dprintf(fd, "now: %ld\n", ds_->now_); dprintf(fd, "is_zipping: %s\n", ds_->IsZipping() ? "true" : "false"); dprintf(fd, "listener: %s\n", ds_->listener_name_.c_str()); dprintf(fd, "notification title: %s\n", ds_->options_->notification_title.c_str()); dprintf(fd, "notification description: %s\n", ds_->options_->notification_description.c_str()); return NO_ERROR; } Loading cmds/dumpstate/DumpstateService.h +5 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,11 @@ class DumpstateService : public BinderService<DumpstateService>, public BnDumpst binder::Status cancelBugreport(); private: Dumpstate& ds_; // Dumpstate object which contains all the bugreporting logic. // Note that dumpstate is a oneshot service, so this object is meant to be used at most for // one bugreport. // This service does not own this object. Dumpstate* ds_; std::mutex lock_; }; Loading cmds/installd/InstalldNativeService.cpp +80 −12 Original line number Diff line number Diff line Loading @@ -158,6 +158,15 @@ binder::Status checkArgumentUuid(const std::unique_ptr<std::string>& uuid) { } } binder::Status checkArgumentUuidTestOrNull(const std::unique_ptr<std::string>& uuid) { if (!uuid || strcmp(uuid->c_str(), kTestUuid) == 0) { return ok(); } else { return exception(binder::Status::EX_ILLEGAL_ARGUMENT, StringPrintf("UUID must be null or \"%s\", got: %s", kTestUuid, uuid->c_str())); } } binder::Status checkArgumentPackageName(const std::string& packageName) { if (is_valid_package_name(packageName.c_str())) { return ok(); Loading Loading @@ -210,6 +219,13 @@ binder::Status checkArgumentPath(const std::unique_ptr<std::string>& path) { } \ } #define CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(uuid) { \ auto status = checkArgumentUuidTestOrNull(uuid); \ if (!status.isOk()) { \ return status; \ } \ } \ #define CHECK_ARGUMENT_PACKAGE_NAME(packageName) { \ binder::Status status = \ checkArgumentPackageName((packageName)); \ Loading Loading @@ -806,20 +822,21 @@ static int32_t copy_directory_recursive(const char* from, const char* to) { binder::Status InstalldNativeService::snapshotAppData( const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName, int32_t user, int32_t storageFlags) { const std::string& packageName, int32_t user, int32_t storageFlags, int64_t* _aidl_return) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard<std::recursive_mutex> lock(mLock); const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr; const char* package_name = packageName.c_str(); if (volume_uuid && strcmp(volume_uuid, kTestUuid)) { return exception(binder::Status::EX_ILLEGAL_ARGUMENT, StringPrintf("volumeUuid must be null or \"%s\", got: %s", kTestUuid, volume_uuid)); } binder::Status res = ok(); // Default result to 0, it will be populated with inode of ce data snapshot // if FLAG_STORAGE_CE has been passed. if (_aidl_return != nullptr) *_aidl_return = 0; bool clear_ce_on_exit = false; bool clear_de_on_exit = false; Loading Loading @@ -900,6 +917,16 @@ binder::Status InstalldNativeService::snapshotAppData( clear_ce_on_exit = true; return res; } if (_aidl_return != nullptr) { auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid, user, package_name); rc = get_path_inode(ce_snapshot_path, reinterpret_cast<ino_t*>(_aidl_return)); if (rc != 0) { res = error(rc, "Failed to get_path_inode for " + ce_snapshot_path); clear_ce_on_exit = true; return res; } } } return res; Loading @@ -910,17 +937,13 @@ binder::Status InstalldNativeService::restoreAppDataSnapshot( const int32_t appId, const int64_t ceDataInode, const std::string& seInfo, const int32_t user, int32_t storageFlags) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard<std::recursive_mutex> lock(mLock); const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr; const char* package_name = packageName.c_str(); if (volume_uuid && strcmp(volume_uuid, kTestUuid)) { return exception(binder::Status::EX_ILLEGAL_ARGUMENT, StringPrintf("volumeUuid must be null or \"%s\", got: %s", kTestUuid, volume_uuid)); } auto from_ce = create_data_misc_ce_rollback_package_path(volume_uuid, user, package_name); auto from_de = create_data_misc_de_rollback_package_path(volume_uuid, Loading Loading @@ -971,6 +994,39 @@ binder::Status InstalldNativeService::restoreAppDataSnapshot( return restoreconAppData(volumeUuid, packageName, user, storageFlags, appId, seInfo); } binder::Status InstalldNativeService::destroyAppDataSnapshot( const std::unique_ptr<std::string> &volumeUuid, const std::string& packageName, const int32_t user, const int64_t ceSnapshotInode, int32_t storageFlags) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard<std::recursive_mutex> lock(mLock); const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr; const char* package_name = packageName.c_str(); if (storageFlags & FLAG_STORAGE_DE) { auto de_snapshot_path = create_data_misc_de_rollback_package_path(volume_uuid, user, package_name); int res = delete_dir_contents_and_dir(de_snapshot_path, true /* ignore_if_missing */); if (res != 0) { return error(res, "Failed clearing snapshot " + de_snapshot_path); } } if (storageFlags & FLAG_STORAGE_CE) { auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid, user, package_name, ceSnapshotInode); int res = delete_dir_contents_and_dir(ce_snapshot_path, true /* ignore_if_missing */); if (res != 0) { return error(res, "Failed clearing snapshot " + ce_snapshot_path); } } return ok(); } binder::Status InstalldNativeService::moveCompleteApp(const std::unique_ptr<std::string>& fromUuid, const std::unique_ptr<std::string>& toUuid, const std::string& packageName, const std::string& dataAppName, int32_t appId, const std::string& seInfo, Loading Loading @@ -2086,8 +2142,14 @@ binder::Status InstalldNativeService::linkNativeLibraryDirectory( return error("Failed to stat " + _pkgdir); } char *con = nullptr; if (lgetfilecon(pkgdir, &con) < 0) { return error("Failed to lgetfilecon " + _pkgdir); } if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) { return error("Failed to chown " + _pkgdir); res = error("Failed to chown " + _pkgdir); goto out; } if (chmod(pkgdir, 0700) < 0) { Loading Loading @@ -2119,7 +2181,13 @@ binder::Status InstalldNativeService::linkNativeLibraryDirectory( goto out; } if (lsetfilecon(libsymlink, con) < 0) { res = error("Failed to lsetfilecon " + _libsymlink); goto out; } out: free(con); if (chmod(pkgdir, s.st_mode) < 0) { auto msg = "Failed to cleanup chmod " + _pkgdir; if (res.isOk()) { Loading cmds/installd/InstalldNativeService.h +5 −1 Original line number Diff line number Diff line Loading @@ -61,10 +61,14 @@ public: binder::Status fixupAppData(const std::unique_ptr<std::string>& uuid, int32_t flags); binder::Status snapshotAppData(const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName, const int32_t user, int32_t storageFlags); const std::string& packageName, const int32_t user, int32_t storageFlags, int64_t* _aidl_return); binder::Status restoreAppDataSnapshot(const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName, const int32_t appId, const int64_t ceDataInode, const std::string& seInfo, const int32_t user, int32_t storageFlags); binder::Status destroyAppDataSnapshot(const std::unique_ptr<std::string> &volumeUuid, const std::string& packageName, const int32_t user, const int64_t ceSnapshotInode, int32_t storageFlags); binder::Status getAppSize(const std::unique_ptr<std::string>& uuid, const std::vector<std::string>& packageNames, int32_t userId, int32_t flags, Loading cmds/installd/binder/android/os/IInstalld.aidl +3 −5 Original line number Diff line number Diff line Loading @@ -105,14 +105,12 @@ interface IInstalld { int userId, int appId, @utf8InCpp String profileName, @utf8InCpp String codePath, @nullable @utf8InCpp String dexMetadata); void snapshotAppData(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName, long snapshotAppData(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName, int userId, int storageFlags); void restoreAppDataSnapshot(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName, int appId, long ceDataInode, @utf8InCpp String seInfo, int user, int storageflags); // TODO(narayan) we need an API to delete the app data snapshot as well. // void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, // in @utf8InCpp String packageName, int userId, int storageFlags); void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName, int userId, long ceSnapshotInode, int storageFlags); const int FLAG_STORAGE_DE = 0x1; const int FLAG_STORAGE_CE = 0x2; Loading Loading
cmds/dumpstate/DumpstateService.cpp +60 −42 Original line number Diff line number Diff line Loading @@ -18,8 +18,9 @@ #include "DumpstateService.h" #include <android-base/stringprintf.h> #include <memory> #include <android-base/stringprintf.h> #include "android/os/BnDumpstate.h" #include "DumpstateInternal.h" Loading Loading @@ -48,9 +49,10 @@ static binder::Status error(uint32_t code, const std::string& msg) { return binder::Status::fromServiceSpecificError(code, String8(msg.c_str())); } // Takes ownership of data. static void* callAndNotify(void* data) { DumpstateInfo& ds_info = *static_cast<DumpstateInfo*>(data); ds_info.ds->Run(ds_info.calling_uid, ds_info.calling_package); std::unique_ptr<DumpstateInfo> ds_info(static_cast<DumpstateInfo*>(data)); ds_info->ds->Run(ds_info->calling_uid, ds_info->calling_package); MYLOGD("Finished Run()\n"); return nullptr; } Loading @@ -59,7 +61,7 @@ class DumpstateToken : public BnDumpstateToken {}; } // namespace DumpstateService::DumpstateService() : ds_(Dumpstate::GetInstance()) { DumpstateService::DumpstateService() : ds_(nullptr) { } char const* DumpstateService::getServiceName() { Loading @@ -78,6 +80,8 @@ status_t DumpstateService::Start() { return android::OK; } // Note: this method is part of the old flow and is not expected to be used in combination // with startBugreport. binder::Status DumpstateService::setListener(const std::string& name, const sp<IDumpstateListener>& listener, bool getSectionDetails, Loading @@ -92,20 +96,22 @@ binder::Status DumpstateService::setListener(const std::string& name, return binder::Status::ok(); } std::lock_guard<std::mutex> lock(lock_); if (ds_.listener_ != nullptr) { MYLOGE("setListener(%s): already set (%s)\n", name.c_str(), ds_.listener_name_.c_str()); if (ds_ == nullptr) { ds_ = &(Dumpstate::GetInstance()); } if (ds_->listener_ != nullptr) { MYLOGE("setListener(%s): already set (%s)\n", name.c_str(), ds_->listener_name_.c_str()); return binder::Status::ok(); } ds_.listener_name_ = name; ds_.listener_ = listener; ds_.report_section_ = getSectionDetails; ds_->listener_name_ = name; ds_->listener_ = listener; ds_->report_section_ = getSectionDetails; *returned_token = new DumpstateToken(); return binder::Status::ok(); } // TODO(b/111441001): Hook up to consent service & copy final br only if user approves. binder::Status DumpstateService::startBugreport(int32_t calling_uid, const std::string& calling_package, const android::base::unique_fd& bugreport_fd, Loading Loading @@ -133,21 +139,29 @@ binder::Status DumpstateService::startBugreport(int32_t calling_uid, options->Initialize(static_cast<Dumpstate::BugreportMode>(bugreport_mode), bugreport_fd, screenshot_fd); // This is the bugreporting API flow, so ensure there is only one bugreport in progress at a // time. std::lock_guard<std::mutex> lock(lock_); // TODO(b/111441001): Disallow multiple simultaneous bugreports. ds_.SetOptions(std::move(options)); if (ds_ != nullptr) { return exception(binder::Status::EX_SERVICE_SPECIFIC, "There is already a bugreport in progress"); } ds_ = &(Dumpstate::GetInstance()); ds_->SetOptions(std::move(options)); if (listener != nullptr) { ds_.listener_ = listener; ds_->listener_ = listener; } DumpstateInfo ds_info; ds_info.ds = &ds_; ds_info.calling_uid = calling_uid; ds_info.calling_package = calling_package; DumpstateInfo* ds_info = new DumpstateInfo(); ds_info->ds = ds_; ds_info->calling_uid = calling_uid; ds_info->calling_package = calling_package; pthread_t thread; status_t err = pthread_create(&thread, nullptr, callAndNotify, &ds_); status_t err = pthread_create(&thread, nullptr, callAndNotify, ds_info); if (err != 0) { delete ds_info; ds_info = nullptr; return error(err, "Could not create a background thread."); } return binder::Status::ok(); Loading @@ -162,32 +176,36 @@ binder::Status DumpstateService::cancelBugreport() { } status_t DumpstateService::dump(int fd, const Vector<String16>&) { std::string destination = ds_.options_->bugreport_fd.get() != -1 ? StringPrintf("[fd:%d]", ds_.options_->bugreport_fd.get()) : ds_.bugreport_internal_dir_.c_str(); dprintf(fd, "id: %d\n", ds_.id_); dprintf(fd, "pid: %d\n", ds_.pid_); dprintf(fd, "update_progress: %s\n", ds_.options_->do_progress_updates ? "true" : "false"); dprintf(fd, "update_progress_threshold: %d\n", ds_.update_progress_threshold_); dprintf(fd, "last_updated_progress: %d\n", ds_.last_updated_progress_); if (ds_ == nullptr) { dprintf(fd, "Bugreport not in progress yet"); return NO_ERROR; } std::string destination = ds_->options_->bugreport_fd.get() != -1 ? StringPrintf("[fd:%d]", ds_->options_->bugreport_fd.get()) : ds_->bugreport_internal_dir_.c_str(); dprintf(fd, "id: %d\n", ds_->id_); dprintf(fd, "pid: %d\n", ds_->pid_); dprintf(fd, "update_progress: %s\n", ds_->options_->do_progress_updates ? "true" : "false"); dprintf(fd, "update_progress_threshold: %d\n", ds_->update_progress_threshold_); dprintf(fd, "last_updated_progress: %d\n", ds_->last_updated_progress_); dprintf(fd, "progress:\n"); ds_.progress_->Dump(fd, " "); dprintf(fd, "args: %s\n", ds_.options_->args.c_str()); dprintf(fd, "extra_options: %s\n", ds_.options_->extra_options.c_str()); dprintf(fd, "version: %s\n", ds_.version_.c_str()); ds_->progress_->Dump(fd, " "); dprintf(fd, "args: %s\n", ds_->options_->args.c_str()); dprintf(fd, "extra_options: %s\n", ds_->options_->extra_options.c_str()); dprintf(fd, "version: %s\n", ds_->version_.c_str()); dprintf(fd, "bugreport_dir: %s\n", destination.c_str()); dprintf(fd, "screenshot_path: %s\n", ds_.screenshot_path_.c_str()); dprintf(fd, "log_path: %s\n", ds_.log_path_.c_str()); dprintf(fd, "tmp_path: %s\n", ds_.tmp_path_.c_str()); dprintf(fd, "path: %s\n", ds_.path_.c_str()); dprintf(fd, "extra_options: %s\n", ds_.options_->extra_options.c_str()); dprintf(fd, "base_name: %s\n", ds_.base_name_.c_str()); dprintf(fd, "name: %s\n", ds_.name_.c_str()); dprintf(fd, "now: %ld\n", ds_.now_); dprintf(fd, "is_zipping: %s\n", ds_.IsZipping() ? "true" : "false"); dprintf(fd, "listener: %s\n", ds_.listener_name_.c_str()); dprintf(fd, "notification title: %s\n", ds_.options_->notification_title.c_str()); dprintf(fd, "notification description: %s\n", ds_.options_->notification_description.c_str()); dprintf(fd, "screenshot_path: %s\n", ds_->screenshot_path_.c_str()); dprintf(fd, "log_path: %s\n", ds_->log_path_.c_str()); dprintf(fd, "tmp_path: %s\n", ds_->tmp_path_.c_str()); dprintf(fd, "path: %s\n", ds_->path_.c_str()); dprintf(fd, "extra_options: %s\n", ds_->options_->extra_options.c_str()); dprintf(fd, "base_name: %s\n", ds_->base_name_.c_str()); dprintf(fd, "name: %s\n", ds_->name_.c_str()); dprintf(fd, "now: %ld\n", ds_->now_); dprintf(fd, "is_zipping: %s\n", ds_->IsZipping() ? "true" : "false"); dprintf(fd, "listener: %s\n", ds_->listener_name_.c_str()); dprintf(fd, "notification title: %s\n", ds_->options_->notification_title.c_str()); dprintf(fd, "notification description: %s\n", ds_->options_->notification_description.c_str()); return NO_ERROR; } Loading
cmds/dumpstate/DumpstateService.h +5 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,11 @@ class DumpstateService : public BinderService<DumpstateService>, public BnDumpst binder::Status cancelBugreport(); private: Dumpstate& ds_; // Dumpstate object which contains all the bugreporting logic. // Note that dumpstate is a oneshot service, so this object is meant to be used at most for // one bugreport. // This service does not own this object. Dumpstate* ds_; std::mutex lock_; }; Loading
cmds/installd/InstalldNativeService.cpp +80 −12 Original line number Diff line number Diff line Loading @@ -158,6 +158,15 @@ binder::Status checkArgumentUuid(const std::unique_ptr<std::string>& uuid) { } } binder::Status checkArgumentUuidTestOrNull(const std::unique_ptr<std::string>& uuid) { if (!uuid || strcmp(uuid->c_str(), kTestUuid) == 0) { return ok(); } else { return exception(binder::Status::EX_ILLEGAL_ARGUMENT, StringPrintf("UUID must be null or \"%s\", got: %s", kTestUuid, uuid->c_str())); } } binder::Status checkArgumentPackageName(const std::string& packageName) { if (is_valid_package_name(packageName.c_str())) { return ok(); Loading Loading @@ -210,6 +219,13 @@ binder::Status checkArgumentPath(const std::unique_ptr<std::string>& path) { } \ } #define CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(uuid) { \ auto status = checkArgumentUuidTestOrNull(uuid); \ if (!status.isOk()) { \ return status; \ } \ } \ #define CHECK_ARGUMENT_PACKAGE_NAME(packageName) { \ binder::Status status = \ checkArgumentPackageName((packageName)); \ Loading Loading @@ -806,20 +822,21 @@ static int32_t copy_directory_recursive(const char* from, const char* to) { binder::Status InstalldNativeService::snapshotAppData( const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName, int32_t user, int32_t storageFlags) { const std::string& packageName, int32_t user, int32_t storageFlags, int64_t* _aidl_return) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard<std::recursive_mutex> lock(mLock); const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr; const char* package_name = packageName.c_str(); if (volume_uuid && strcmp(volume_uuid, kTestUuid)) { return exception(binder::Status::EX_ILLEGAL_ARGUMENT, StringPrintf("volumeUuid must be null or \"%s\", got: %s", kTestUuid, volume_uuid)); } binder::Status res = ok(); // Default result to 0, it will be populated with inode of ce data snapshot // if FLAG_STORAGE_CE has been passed. if (_aidl_return != nullptr) *_aidl_return = 0; bool clear_ce_on_exit = false; bool clear_de_on_exit = false; Loading Loading @@ -900,6 +917,16 @@ binder::Status InstalldNativeService::snapshotAppData( clear_ce_on_exit = true; return res; } if (_aidl_return != nullptr) { auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid, user, package_name); rc = get_path_inode(ce_snapshot_path, reinterpret_cast<ino_t*>(_aidl_return)); if (rc != 0) { res = error(rc, "Failed to get_path_inode for " + ce_snapshot_path); clear_ce_on_exit = true; return res; } } } return res; Loading @@ -910,17 +937,13 @@ binder::Status InstalldNativeService::restoreAppDataSnapshot( const int32_t appId, const int64_t ceDataInode, const std::string& seInfo, const int32_t user, int32_t storageFlags) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard<std::recursive_mutex> lock(mLock); const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr; const char* package_name = packageName.c_str(); if (volume_uuid && strcmp(volume_uuid, kTestUuid)) { return exception(binder::Status::EX_ILLEGAL_ARGUMENT, StringPrintf("volumeUuid must be null or \"%s\", got: %s", kTestUuid, volume_uuid)); } auto from_ce = create_data_misc_ce_rollback_package_path(volume_uuid, user, package_name); auto from_de = create_data_misc_de_rollback_package_path(volume_uuid, Loading Loading @@ -971,6 +994,39 @@ binder::Status InstalldNativeService::restoreAppDataSnapshot( return restoreconAppData(volumeUuid, packageName, user, storageFlags, appId, seInfo); } binder::Status InstalldNativeService::destroyAppDataSnapshot( const std::unique_ptr<std::string> &volumeUuid, const std::string& packageName, const int32_t user, const int64_t ceSnapshotInode, int32_t storageFlags) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); std::lock_guard<std::recursive_mutex> lock(mLock); const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr; const char* package_name = packageName.c_str(); if (storageFlags & FLAG_STORAGE_DE) { auto de_snapshot_path = create_data_misc_de_rollback_package_path(volume_uuid, user, package_name); int res = delete_dir_contents_and_dir(de_snapshot_path, true /* ignore_if_missing */); if (res != 0) { return error(res, "Failed clearing snapshot " + de_snapshot_path); } } if (storageFlags & FLAG_STORAGE_CE) { auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid, user, package_name, ceSnapshotInode); int res = delete_dir_contents_and_dir(ce_snapshot_path, true /* ignore_if_missing */); if (res != 0) { return error(res, "Failed clearing snapshot " + ce_snapshot_path); } } return ok(); } binder::Status InstalldNativeService::moveCompleteApp(const std::unique_ptr<std::string>& fromUuid, const std::unique_ptr<std::string>& toUuid, const std::string& packageName, const std::string& dataAppName, int32_t appId, const std::string& seInfo, Loading Loading @@ -2086,8 +2142,14 @@ binder::Status InstalldNativeService::linkNativeLibraryDirectory( return error("Failed to stat " + _pkgdir); } char *con = nullptr; if (lgetfilecon(pkgdir, &con) < 0) { return error("Failed to lgetfilecon " + _pkgdir); } if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) { return error("Failed to chown " + _pkgdir); res = error("Failed to chown " + _pkgdir); goto out; } if (chmod(pkgdir, 0700) < 0) { Loading Loading @@ -2119,7 +2181,13 @@ binder::Status InstalldNativeService::linkNativeLibraryDirectory( goto out; } if (lsetfilecon(libsymlink, con) < 0) { res = error("Failed to lsetfilecon " + _libsymlink); goto out; } out: free(con); if (chmod(pkgdir, s.st_mode) < 0) { auto msg = "Failed to cleanup chmod " + _pkgdir; if (res.isOk()) { Loading
cmds/installd/InstalldNativeService.h +5 −1 Original line number Diff line number Diff line Loading @@ -61,10 +61,14 @@ public: binder::Status fixupAppData(const std::unique_ptr<std::string>& uuid, int32_t flags); binder::Status snapshotAppData(const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName, const int32_t user, int32_t storageFlags); const std::string& packageName, const int32_t user, int32_t storageFlags, int64_t* _aidl_return); binder::Status restoreAppDataSnapshot(const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName, const int32_t appId, const int64_t ceDataInode, const std::string& seInfo, const int32_t user, int32_t storageFlags); binder::Status destroyAppDataSnapshot(const std::unique_ptr<std::string> &volumeUuid, const std::string& packageName, const int32_t user, const int64_t ceSnapshotInode, int32_t storageFlags); binder::Status getAppSize(const std::unique_ptr<std::string>& uuid, const std::vector<std::string>& packageNames, int32_t userId, int32_t flags, Loading
cmds/installd/binder/android/os/IInstalld.aidl +3 −5 Original line number Diff line number Diff line Loading @@ -105,14 +105,12 @@ interface IInstalld { int userId, int appId, @utf8InCpp String profileName, @utf8InCpp String codePath, @nullable @utf8InCpp String dexMetadata); void snapshotAppData(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName, long snapshotAppData(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName, int userId, int storageFlags); void restoreAppDataSnapshot(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName, int appId, long ceDataInode, @utf8InCpp String seInfo, int user, int storageflags); // TODO(narayan) we need an API to delete the app data snapshot as well. // void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, // in @utf8InCpp String packageName, int userId, int storageFlags); void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName, int userId, long ceSnapshotInode, int storageFlags); const int FLAG_STORAGE_DE = 0x1; const int FLAG_STORAGE_CE = 0x2; Loading