From 60636cdc57f8b03912ffb714a4a3f4a890908d42 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 7 Mar 2020 20:48:47 -0800 Subject: [PATCH] updater: use fs bindings --- .../stratosphere/sm/sm_scoped_holder.hpp | 7 +- .../source/updater/updater_api.cpp | 163 +++++++++--------- .../source/updater/updater_bis_management.cpp | 43 ++--- .../source/updater/updater_bis_management.hpp | 42 ++--- .../source/updater/updater_files.cpp | 52 +++--- .../source/updater/updater_paths.cpp | 13 +- .../source/updater/updater_paths.hpp | 2 +- 7 files changed, 152 insertions(+), 170 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp b/libraries/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp index a0cd09e0f..ecc9e1629 100644 --- a/libraries/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp +++ b/libraries/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp @@ -65,7 +65,12 @@ namespace ams::sm { AMS_ABORT_UNLESS(!this->has_initialized); sm::DoWithSession([&]() { - this->result = Initializer(); + if constexpr (std::is_same::value) { + Initializer(); + this->result = ResultSuccess(); + } else { + this->result = Initializer(); + } }); this->has_initialized = R_SUCCEEDED(this->result); diff --git a/libraries/libstratosphere/source/updater/updater_api.cpp b/libraries/libstratosphere/source/updater/updater_api.cpp index 33c417188..55551c7e4 100644 --- a/libraries/libstratosphere/source/updater/updater_api.cpp +++ b/libraries/libstratosphere/source/updater/updater_api.cpp @@ -32,25 +32,26 @@ namespace ams::updater { /* Configuration Prototypes. */ bool HasEks(BootImageUpdateType boot_image_update_type); bool HasAutoRcmPreserve(BootImageUpdateType boot_image_update_type); - NcmContentMetaType GetNcmContentMetaType(BootModeType mode); - Result GetBootImagePackageDataId(u64 *out_data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size); + ncm::ContentMetaType GetContentMetaType(BootModeType mode); + Result GetBootImagePackageId(ncm::SystemDataId *out_data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size); /* Verification Prototypes. */ Result GetVerificationState(VerificationState *out, void *work_buffer, size_t work_buffer_size); - Result VerifyBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - Result VerifyBootImagesNormal(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - Result VerifyBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); + Result VerifyBootImages(ncm::SystemDataId data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); + Result VerifyBootImagesNormal(ncm::SystemDataId data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); + Result VerifyBootImagesSafe(ncm::SystemDataId data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); /* Update Prototypes. */ Result SetVerificationNeeded(BootModeType mode, bool needed, void *work_buffer, size_t work_buffer_size); - Result UpdateBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - Result UpdateBootImagesNormal(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); - Result UpdateBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); + Result UpdateBootImages(ncm::SystemDataId data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); + Result UpdateBootImagesNormal(ncm::SystemDataId data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); + Result UpdateBootImagesSafe(ncm::SystemDataId data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); /* Package helpers. */ Result ValidateBctFileHash(Boot0Accessor &accessor, Boot0Partition which, const void *stored_hash, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type); Result GetPackage2Hash(void *dst_hash, size_t package2_size, void *work_buffer, size_t work_buffer_size, Package2Type which); Result WritePackage2(void *work_buffer, size_t work_buffer_size, Package2Type which, BootImageUpdateType boot_image_update_type); + Result CompareHash(const void *lhs, const void *rhs, size_t size); /* Implementations. */ Result ValidateWorkBuffer(const void *work_buffer, size_t work_buffer_size) { @@ -80,12 +81,12 @@ namespace ams::updater { } } - NcmContentMetaType GetNcmContentMetaType(BootModeType mode) { + ncm::ContentMetaType GetContentMetaType(BootModeType mode) { switch (mode) { case BootModeType::Normal: - return NcmContentMetaType_BootImagePackage; + return ncm::ContentMetaType::BootImagePackage; case BootModeType::Safe: - return NcmContentMetaType_BootImagePackageSafe; + return ncm::ContentMetaType::BootImagePackageSafe; AMS_UNREACHABLE_DEFAULT_CASE(); } } @@ -114,8 +115,8 @@ namespace ams::updater { Result VerifyBootImagesAndRepairIfNeeded(bool *out_repaired, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { /* Get system data id for boot images (819/81A/81B/81C). */ - u64 bip_data_id = 0; - R_TRY(GetBootImagePackageDataId(&bip_data_id, mode, work_buffer, work_buffer_size)); + ncm::SystemDataId bip_data_id; + R_TRY(GetBootImagePackageId(&bip_data_id, mode, work_buffer, work_buffer_size)); /* Verify the boot images in NAND. */ R_TRY_CATCH(VerifyBootImages(bip_data_id, mode, work_buffer, work_buffer_size, boot_image_update_type)) { @@ -130,47 +131,40 @@ namespace ams::updater { return SetVerificationNeeded(mode, false, work_buffer, work_buffer_size); } - Result GetBootImagePackageDataId(u64 *out_data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size) { + Result GetBootImagePackageId(ncm::SystemDataId *out_data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size) { /* Ensure we can read content metas. */ constexpr size_t MaxContentMetas = 0x40; - AMS_ABORT_UNLESS(work_buffer_size >= sizeof(NcmContentMetaKey) * MaxContentMetas); + AMS_ABORT_UNLESS(work_buffer_size >= sizeof(ncm::ContentMetaKey) * MaxContentMetas); /* Open NAND System meta database, list contents. */ - NcmContentMetaDatabase meta_db; - R_TRY(ncmOpenContentMetaDatabase(&meta_db, NcmStorageId_BuiltInSystem)); - ON_SCOPE_EXIT { serviceClose(&meta_db.s); }; + ncm::ContentMetaDatabase db; + R_TRY(ncm::OpenContentMetaDatabase(std::addressof(db), ncm::StorageId::BuiltInSystem)); - NcmContentMetaKey *records = reinterpret_cast(work_buffer); + ncm::ContentMetaKey *keys = reinterpret_cast(work_buffer); + const auto content_meta_type = GetContentMetaType(mode); - const auto content_meta_type = GetNcmContentMetaType(mode); - s32 written_entries; - s32 total_entries; - R_TRY(ncmContentMetaDatabaseList(&meta_db, &total_entries, &written_entries, records, MaxContentMetas * sizeof(*records), content_meta_type, 0, 0, UINT64_MAX, NcmContentInstallType_Full)); - if (total_entries <= 0) { - return ResultBootImagePackageNotFound(); - } - - AMS_ABORT_UNLESS(total_entries == written_entries); + auto count = db.ListContentMeta(keys, MaxContentMetas, content_meta_type); + R_UNLESS(count.total > 0, ResultBootImagePackageNotFound()); /* Output is sorted, return the lowest valid exfat entry. */ - if (total_entries > 1) { - for (size_t i = 0; i < size_t(total_entries); i++) { + if (count.total > 1) { + for (auto i = 0; i < count.total; i++) { u8 attr; - R_TRY(ncmContentMetaDatabaseGetAttributes(&meta_db, &records[i], &attr)); + R_TRY(db.GetAttributes(std::addressof(attr), keys[i])); - if (attr & NcmContentMetaAttribute_IncludesExFatDriver) { - *out_data_id = records[i].id; + if (attr & ncm::ContentMetaAttribute_IncludesExFatDriver) { + out_data_id->value = keys[i].id; return ResultSuccess(); } } } /* If there's only one entry or no exfat entries, return that entry. */ - *out_data_id = records[0].id; + out_data_id->value = keys[0].id; return ResultSuccess(); } - Result VerifyBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { + Result VerifyBootImages(ncm::SystemDataId data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { switch (mode) { case BootModeType::Normal: return VerifyBootImagesNormal(data_id, work_buffer, work_buffer_size, boot_image_update_type); @@ -180,20 +174,22 @@ namespace ams::updater { } } - Result VerifyBootImagesNormal(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { + Result VerifyBootImagesNormal(ncm::SystemDataId data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { /* Ensure work buffer is big enough for us to do what we want to do. */ R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - R_TRY_CATCH(romfsMountFromDataArchive(data_id, NcmStorageId_BuiltInSystem, GetBootImagePackageMountPath())) { + /* Mount the boot image package. */ + const char *mount_name = GetMountName(); + R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) { R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound()) } R_END_TRY_CATCH; - ON_SCOPE_EXIT { R_ABORT_UNLESS(romfsUnmount(GetBootImagePackageMountPath())); }; + ON_SCOPE_EXIT { fs::Unmount(mount_name); }; /* Read and validate hashes of boot images. */ { size_t size; - u8 nand_hash[SHA256_HASH_SIZE]; - u8 file_hash[SHA256_HASH_SIZE]; + u8 nand_hash[crypto::Sha256Generator::HashSize]; + u8 file_hash[crypto::Sha256Generator::HashSize]; Boot0Accessor boot0_accessor; R_TRY(boot0_accessor.Initialize()); @@ -209,44 +205,42 @@ namespace ams::updater { /* Compare Package1 Normal/Sub hashes. */ R_TRY(GetFileHash(&size, file_hash, GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size)); + R_TRY(boot0_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot0Partition::Package1NormalMain)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultNeedsRepairBootImages(); - } + R_TRY(CompareHash(file_hash, nand_hash, sizeof(file_hash))); + R_TRY(boot0_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot0Partition::Package1NormalSub)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultNeedsRepairBootImages(); - } + R_TRY(CompareHash(file_hash, nand_hash, sizeof(file_hash))); /* Compare Package2 Normal/Sub hashes. */ R_TRY(GetFileHash(&size, file_hash, GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size)); + R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::NormalMain)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultNeedsRepairBootImages(); - } + R_TRY(CompareHash(file_hash, nand_hash, sizeof(file_hash))); + R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::NormalSub)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultNeedsRepairBootImages(); - } + R_TRY(CompareHash(file_hash, nand_hash, sizeof(file_hash))); } return ResultSuccess(); } - Result VerifyBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { + Result VerifyBootImagesSafe(ncm::SystemDataId data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { /* Ensure work buffer is big enough for us to do what we want to do. */ R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - R_TRY_CATCH(romfsMountFromDataArchive(data_id, NcmStorageId_BuiltInSystem, GetBootImagePackageMountPath())) { + /* Mount the boot image package. */ + const char *mount_name = GetMountName(); + R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) { R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound()) } R_END_TRY_CATCH; - ON_SCOPE_EXIT { R_ABORT_UNLESS(romfsUnmount(GetBootImagePackageMountPath())); }; + ON_SCOPE_EXIT { fs::Unmount(mount_name); }; /* Read and validate hashes of boot images. */ { size_t size; - u8 nand_hash[SHA256_HASH_SIZE]; - u8 file_hash[SHA256_HASH_SIZE]; + u8 nand_hash[crypto::Sha256Generator::HashSize]; + u8 file_hash[crypto::Sha256Generator::HashSize]; Boot0Accessor boot0_accessor; R_TRY(boot0_accessor.Initialize()); @@ -267,31 +261,27 @@ namespace ams::updater { /* Compare Package1 Normal/Sub hashes. */ R_TRY(GetFileHash(&size, file_hash, GetPackage1Path(boot_image_update_type), work_buffer, work_buffer_size)); + R_TRY(boot1_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot1Partition::Package1SafeMain)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultNeedsRepairBootImages(); - } + R_TRY(CompareHash(file_hash, nand_hash, sizeof(file_hash))); + R_TRY(boot1_accessor.GetHash(nand_hash, size, work_buffer, work_buffer_size, Boot1Partition::Package1SafeSub)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultNeedsRepairBootImages(); - } + R_TRY(CompareHash(file_hash, nand_hash, sizeof(file_hash))); /* Compare Package2 Normal/Sub hashes. */ R_TRY(GetFileHash(&size, file_hash, GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size)); + R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::SafeMain)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultNeedsRepairBootImages(); - } + R_TRY(CompareHash(file_hash, nand_hash, sizeof(file_hash))); + R_TRY(GetPackage2Hash(nand_hash, size, work_buffer, work_buffer_size, Package2Type::SafeSub)); - if (std::memcmp(file_hash, nand_hash, SHA256_HASH_SIZE) != 0) { - return ResultNeedsRepairBootImages(); - } + R_TRY(CompareHash(file_hash, nand_hash, sizeof(file_hash))); } return ResultSuccess(); } - Result UpdateBootImages(u64 data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { + Result UpdateBootImages(ncm::SystemDataId data_id, BootModeType mode, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { switch (mode) { case BootModeType::Normal: return UpdateBootImagesNormal(data_id, work_buffer, work_buffer_size, boot_image_update_type); @@ -301,14 +291,16 @@ namespace ams::updater { } } - Result UpdateBootImagesNormal(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { + Result UpdateBootImagesNormal(ncm::SystemDataId data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { /* Ensure work buffer is big enough for us to do what we want to do. */ R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - R_TRY_CATCH(romfsMountFromDataArchive(data_id, NcmStorageId_BuiltInSystem, GetBootImagePackageMountPath())) { + /* Mount the boot image package. */ + const char *mount_name = GetMountName(); + R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) { R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound()) } R_END_TRY_CATCH; - ON_SCOPE_EXIT { R_ABORT_UNLESS(romfsUnmount(GetBootImagePackageMountPath())); }; + ON_SCOPE_EXIT { fs::Unmount(mount_name); }; { Boot0Accessor boot0_accessor; @@ -356,14 +348,16 @@ namespace ams::updater { return ResultSuccess(); } - Result UpdateBootImagesSafe(u64 data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { + Result UpdateBootImagesSafe(ncm::SystemDataId data_id, void *work_buffer, size_t work_buffer_size, BootImageUpdateType boot_image_update_type) { /* Ensure work buffer is big enough for us to do what we want to do. */ R_TRY(ValidateWorkBuffer(work_buffer, work_buffer_size)); - R_TRY_CATCH(romfsMountFromDataArchive(data_id, NcmStorageId_BuiltInSystem, GetBootImagePackageMountPath())) { + /* Mount the boot image package. */ + const char *mount_name = GetMountName(); + R_TRY_CATCH(fs::MountSystemData(mount_name, data_id)) { R_CONVERT(fs::ResultTargetNotFound, ResultBootImagePackageNotFound()) } R_END_TRY_CATCH; - ON_SCOPE_EXIT { R_ABORT_UNLESS(romfsUnmount(GetBootImagePackageMountPath())); }; + ON_SCOPE_EXIT { fs::Unmount(mount_name); }; { Boot0Accessor boot0_accessor; @@ -450,14 +444,10 @@ namespace ams::updater { R_TRY(accessor.PreserveAutoRcm(bct, work, which)); } - u8 file_hash[SHA256_HASH_SIZE]; - sha256CalculateHash(file_hash, bct, BctSize); + u8 file_hash[crypto::Sha256Generator::HashSize]; + crypto::GenerateSha256Hash(file_hash, sizeof(file_hash), bct, BctSize); - if (std::memcmp(file_hash, stored_hash, SHA256_HASH_SIZE) != 0) { - return ResultNeedsRepairBootImages(); - } - - return ResultSuccess(); + return CompareHash(file_hash, stored_hash, sizeof(file_hash)); } Result GetPackage2Hash(void *dst_hash, size_t package2_size, void *work_buffer, size_t work_buffer_size, Package2Type which) { @@ -476,6 +466,11 @@ namespace ams::updater { return accessor.Write(GetPackage2Path(boot_image_update_type), work_buffer, work_buffer_size, Package2Partition::Package2); } + Result CompareHash(const void *lhs, const void *rhs, size_t size) { + R_UNLESS(crypto::IsSameBytes(lhs, rhs, size), ResultNeedsRepairBootImages()); + return ResultSuccess(); + } + } BootImageUpdateType GetBootImageUpdateType(spl::HardwareType hw_type) { @@ -508,7 +503,7 @@ namespace ams::updater { } /* Get a session to ncm. */ - sm::ScopedServiceHolder ncm_holder; + sm::ScopedServiceHolder ncm_holder; R_ABORT_UNLESS(ncm_holder.GetResult()); /* Verify normal, verify safe as needed. */ diff --git a/libraries/libstratosphere/source/updater/updater_bis_management.cpp b/libraries/libstratosphere/source/updater/updater_bis_management.cpp index 709396aca..9e5879918 100644 --- a/libraries/libstratosphere/source/updater/updater_bis_management.cpp +++ b/libraries/libstratosphere/source/updater/updater_bis_management.cpp @@ -18,47 +18,38 @@ namespace ams::updater { Result BisAccessor::Initialize() { - R_TRY(fsOpenBisStorage(&this->storage, this->partition_id)); - this->active = true; - return ResultSuccess(); + return fs::OpenBisPartition(std::addressof(this->storage), this->partition_id); } void BisAccessor::Finalize() { - if (this->active) { - fsStorageClose(&this->storage); - this->active = false; - } + /* ... */ } Result BisAccessor::Read(void *dst, size_t size, u64 offset) { AMS_ABORT_UNLESS((offset % SectorAlignment) == 0); - return fsStorageRead(&this->storage, offset, dst, size); + return this->storage->Read(static_cast(offset), dst, size); } Result BisAccessor::Write(u64 offset, const void *src, size_t size) { AMS_ABORT_UNLESS((offset % SectorAlignment) == 0); - return fsStorageWrite(&this->storage, offset, src, size); + return this->storage->Write(static_cast(offset), src, size); } Result BisAccessor::Write(u64 offset, size_t size, const char *bip_path, void *work_buffer, size_t work_buffer_size) { AMS_ABORT_UNLESS((offset % SectorAlignment) == 0); AMS_ABORT_UNLESS((work_buffer_size % SectorAlignment) == 0); - FILE *bip_fp = fopen(bip_path, "rb"); - if (bip_fp == NULL) { - return ResultInvalidBootImagePackage(); - } - ON_SCOPE_EXIT { fclose(bip_fp); }; + fs::FileHandle file; + R_TRY_CATCH(fs::OpenFile(std::addressof(file), bip_path, fs::OpenMode_Read)) { + R_CONVERT(fs::ResultPathNotFound, ResultInvalidBootImagePackage()) + } R_END_TRY_CATCH; + ON_SCOPE_EXIT { fs::CloseFile(file); }; size_t written = 0; while (true) { std::memset(work_buffer, 0, work_buffer_size); - size_t read_size = fread(work_buffer, 1, work_buffer_size, bip_fp); - if (read_size != work_buffer_size) { - if (ferror(bip_fp)) { - return fsdevGetLastResult(); - } - } + size_t read_size; + R_TRY(fs::ReadFile(std::addressof(read_size), file, written, work_buffer, work_buffer_size, fs::ReadOption())); AMS_ABORT_UNLESS(written + read_size <= size); size_t aligned_size = ((read_size + SectorAlignment - 1) / SectorAlignment) * SectorAlignment; @@ -91,18 +82,19 @@ namespace ams::updater { AMS_ABORT_UNLESS((offset % SectorAlignment) == 0); AMS_ABORT_UNLESS((work_buffer_size % SectorAlignment) == 0); - Sha256Context sha_ctx; - sha256ContextCreate(&sha_ctx); + crypto::Sha256Generator generator; + generator.Initialize(); size_t total_read = 0; while (total_read < hash_size) { size_t cur_read_size = std::min(work_buffer_size, size - total_read); size_t cur_update_size = std::min(cur_read_size, hash_size - total_read); R_TRY(this->Read(work_buffer, cur_read_size, offset + total_read)); - sha256ContextUpdate(&sha_ctx, work_buffer, cur_update_size); + generator.Update(work_buffer, cur_update_size); + total_read += cur_read_size; } - sha256ContextGetHash(&sha_ctx, dst); + generator.GetHash(dst, hash_size); return ResultSuccess(); } @@ -140,9 +132,10 @@ namespace ams::updater { size_t read_size; R_TRY(this->Read(&read_size, work_buffer, BctSize, which)); - void *dst_pubk = reinterpret_cast(reinterpret_cast(dst_bct) + BctPubkOffset); + void *dst_pubk = reinterpret_cast(reinterpret_cast(dst_bct) + BctPubkOffset); void *src_pubk = reinterpret_cast(reinterpret_cast(work_buffer) + BctPubkOffset); std::memcpy(dst_pubk, src_pubk, BctPubkSize); + return ResultSuccess(); } diff --git a/libraries/libstratosphere/source/updater/updater_bis_management.hpp b/libraries/libstratosphere/source/updater/updater_bis_management.hpp index d0fdbd25d..c98333f6e 100644 --- a/libraries/libstratosphere/source/updater/updater_bis_management.hpp +++ b/libraries/libstratosphere/source/updater/updater_bis_management.hpp @@ -20,19 +20,14 @@ namespace ams::updater { class BisAccessor { + NON_COPYABLE(BisAccessor); public: static constexpr size_t SectorAlignment = 0x200; private: - FsStorage storage = {}; - FsBisPartitionId partition_id; - bool active; + std::unique_ptr storage; + const fs::BisPartitionId partition_id; public: - BisAccessor(FsBisPartitionId id) : partition_id(id), active(false) { } - ~BisAccessor() { - if (this->active) { - fsStorageClose(&storage); - } - } + explicit BisAccessor(fs::BisPartitionId id) : partition_id(id) { /* ... */ } public: Result Initialize(); @@ -79,7 +74,7 @@ namespace ams::updater { }; struct Boot0Meta { - using EnumType = Boot0Partition; + using EnumType = Boot0Partition; using OffsetSizeType = OffsetSizeEntry; static constexpr size_t NumEntries = static_cast(EnumType::Count); @@ -96,7 +91,7 @@ namespace ams::updater { }; struct Boot1Meta { - using EnumType = Boot1Partition; + using EnumType = Boot1Partition; using OffsetSizeType = OffsetSizeEntry; static constexpr size_t NumEntries = static_cast(EnumType::Count); @@ -109,7 +104,7 @@ namespace ams::updater { }; struct Package2Meta { - using EnumType = Package2Partition; + using EnumType = Package2Partition; using OffsetSizeType = OffsetSizeEntry; static constexpr size_t NumEntries = static_cast(EnumType::Count); @@ -121,11 +116,12 @@ namespace ams::updater { template class PartitionAccessor : public BisAccessor { + NON_COPYABLE(PartitionAccessor); public: - using EnumType = typename Meta::EnumType; + using EnumType = typename Meta::EnumType; using OffsetSizeType = typename Meta::OffsetSizeType; public: - PartitionAccessor(FsBisPartitionId id) : BisAccessor(id) { } + explicit PartitionAccessor(fs::BisPartitionId id) : BisAccessor(id) { /* ... */ } private: constexpr const OffsetSizeType *FindEntry(EnumType which) { const OffsetSizeType *entry = nullptr; @@ -182,27 +178,27 @@ namespace ams::updater { RepairSub, }; - static constexpr FsBisPartitionId GetPackage2StorageId(Package2Type which) { + static constexpr fs::BisPartitionId GetPackage2StorageId(Package2Type which) { switch (which) { case Package2Type::NormalMain: - return FsBisPartitionId_BootConfigAndPackage2Part1; + return fs::BisPartitionId::BootConfigAndPackage2Part1; case Package2Type::NormalSub: - return FsBisPartitionId_BootConfigAndPackage2Part2; + return fs::BisPartitionId::BootConfigAndPackage2Part2; case Package2Type::SafeMain: - return FsBisPartitionId_BootConfigAndPackage2Part3; + return fs::BisPartitionId::BootConfigAndPackage2Part3; case Package2Type::SafeSub: - return FsBisPartitionId_BootConfigAndPackage2Part4; + return fs::BisPartitionId::BootConfigAndPackage2Part4; case Package2Type::RepairMain: - return FsBisPartitionId_BootConfigAndPackage2Part5; + return fs::BisPartitionId::BootConfigAndPackage2Part5; case Package2Type::RepairSub: - return FsBisPartitionId_BootConfigAndPackage2Part6; + return fs::BisPartitionId::BootConfigAndPackage2Part6; AMS_UNREACHABLE_DEFAULT_CASE(); } } class Boot0Accessor : public PartitionAccessor { public: - static constexpr FsBisPartitionId PartitionId = FsBisPartitionId_BootPartition1Root; + static constexpr fs::BisPartitionId PartitionId = fs::BisPartitionId::BootPartition1Root; static constexpr size_t BctPubkOffset = 0x210; static constexpr size_t BctPubkSize = 0x100; static constexpr size_t BctEksOffset = 0x450; @@ -222,7 +218,7 @@ namespace ams::updater { class Boot1Accessor : public PartitionAccessor { public: - static constexpr FsBisPartitionId PartitionId = FsBisPartitionId_BootPartition2Root; + static constexpr fs::BisPartitionId PartitionId = fs::BisPartitionId::BootPartition2Root; public: Boot1Accessor() : PartitionAccessor(PartitionId) { } }; diff --git a/libraries/libstratosphere/source/updater/updater_files.cpp b/libraries/libstratosphere/source/updater/updater_files.cpp index e523fb3de..3266862f9 100644 --- a/libraries/libstratosphere/source/updater/updater_files.cpp +++ b/libraries/libstratosphere/source/updater/updater_files.cpp @@ -18,49 +18,43 @@ namespace ams::updater { Result ReadFile(size_t *out_size, void *dst, size_t dst_size, const char *path) { - FILE *fp = fopen(path, "rb"); - if (fp == NULL) { - return ResultInvalidBootImagePackage(); - } - ON_SCOPE_EXIT { fclose(fp); }; + /* Open the file. */ + fs::FileHandle file; + R_TRY_CATCH(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read)) { + R_CONVERT(fs::ResultPathNotFound, ResultInvalidBootImagePackage()) + } R_END_TRY_CATCH; + ON_SCOPE_EXIT { fs::CloseFile(file); }; std::memset(dst, 0, dst_size); - size_t read_size = fread(dst, 1, dst_size, fp); - if (ferror(fp)) { - return fsdevGetLastResult(); - } - *out_size = read_size; - return ResultSuccess(); + return fs::ReadFile(out_size, file, 0, dst, dst_size, fs::ReadOption()); } Result GetFileHash(size_t *out_size, void *dst_hash, const char *path, void *work_buffer, size_t work_buffer_size) { - FILE *fp = fopen(path, "rb"); - if (fp == NULL) { - return ResultInvalidBootImagePackage(); - } - ON_SCOPE_EXIT { fclose(fp); }; + /* Open the file. */ + fs::FileHandle file; + R_TRY_CATCH(fs::OpenFile(std::addressof(file), path, fs::OpenMode_Read)) { + R_CONVERT(fs::ResultPathNotFound, ResultInvalidBootImagePackage()) + } R_END_TRY_CATCH; + ON_SCOPE_EXIT { fs::CloseFile(file); }; - Sha256Context sha_ctx; - sha256ContextCreate(&sha_ctx); + /* Read in chunks, hashing as we go. */ + crypto::Sha256Generator generator; + generator.Initialize(); size_t total_size = 0; while (true) { - size_t read_size = fread(work_buffer, 1, work_buffer_size, fp); - if (ferror(fp)) { - return fsdevGetLastResult(); - } - if (read_size == 0) { - break; - } + size_t size; + R_TRY(fs::ReadFile(std::addressof(size), file, total_size, work_buffer, work_buffer_size, fs::ReadOption())); - sha256ContextUpdate(&sha_ctx, work_buffer, read_size); - total_size += read_size; - if (read_size != work_buffer_size) { + generator.Update(work_buffer, size); + total_size += size; + + if (size != work_buffer_size) { break; } } - sha256ContextGetHash(&sha_ctx, dst_hash); + generator.GetHash(dst_hash, crypto::Sha256Generator::HashSize); *out_size = total_size; return ResultSuccess(); } diff --git a/libraries/libstratosphere/source/updater/updater_paths.cpp b/libraries/libstratosphere/source/updater/updater_paths.cpp index f6a436d5d..6ede7d00d 100644 --- a/libraries/libstratosphere/source/updater/updater_paths.cpp +++ b/libraries/libstratosphere/source/updater/updater_paths.cpp @@ -13,7 +13,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include #include "updater_paths.hpp" namespace ams::updater { @@ -21,7 +20,7 @@ namespace ams::updater { namespace { /* Actual paths. */ - constexpr const char *BootImagePackageMountPath = "bip"; + constexpr const char *BootImagePackageMountName = "bip"; constexpr const char *BctPathNx = "bip:/nx/bct"; constexpr const char *Package1PathNx = "bip:/nx/package1"; constexpr const char *Package2PathNx = "bip:/nx/package2"; @@ -33,12 +32,12 @@ namespace ams::updater { AMS_ABORT_UNLESS(num_candidates > 0); for (size_t i = 0; i < num_candidates; i++) { - struct stat buf; - if (stat(candidates[i], &buf) != 0) { + fs::DirectoryEntryType type; + if (R_FAILED(fs::GetEntryType(std::addressof(type), candidates[i]))) { continue; } - if (!S_ISREG(buf.st_mode)) { + if (type != fs::DirectoryEntryType_File) { continue; } @@ -51,8 +50,8 @@ namespace ams::updater { } - const char *GetBootImagePackageMountPath() { - return BootImagePackageMountPath; + const char *GetMountName() { + return BootImagePackageMountName; } diff --git a/libraries/libstratosphere/source/updater/updater_paths.hpp b/libraries/libstratosphere/source/updater/updater_paths.hpp index 0627280f6..f6f5c4c2a 100644 --- a/libraries/libstratosphere/source/updater/updater_paths.hpp +++ b/libraries/libstratosphere/source/updater/updater_paths.hpp @@ -19,7 +19,7 @@ namespace ams::updater { /* Path functionality. */ - const char *GetBootImagePackageMountPath(); + const char *GetMountName(); const char *GetBctPath(BootImageUpdateType boot_image_update_type); const char *GetPackage1Path(BootImageUpdateType boot_image_update_type); const char *GetPackage2Path(BootImageUpdateType boot_image_update_type);