From 20dcbf8664528000ee2f919fe473ff2dcea4fad2 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Tue, 29 Jun 2021 13:00:32 -0700 Subject: [PATCH] Fix a permissions bug when creating system save data --- src/LibHac/FsSrv/SaveDataFileSystemService.cs | 12 +++--- .../ShimTests/SaveDataManagement.cs | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/LibHac/FsSrv/SaveDataFileSystemService.cs b/src/LibHac/FsSrv/SaveDataFileSystemService.cs index ab481e19..354d02b7 100644 --- a/src/LibHac/FsSrv/SaveDataFileSystemService.cs +++ b/src/LibHac/FsSrv/SaveDataFileSystemService.cs @@ -965,22 +965,22 @@ namespace LibHac.FsSrv if (!IsStaticSaveDataIdValueRange(attribute.StaticSaveDataId)) return ResultFs.InvalidArgument.Log(); - SaveDataCreationInfo newCreationInfo = creationInfo; + SaveDataCreationInfo tempCreationInfo = creationInfo; - if (newCreationInfo.OwnerId == 0) + if (tempCreationInfo.OwnerId == 0) { - newCreationInfo.OwnerId = programInfo.ProgramIdValue; + tempCreationInfo.OwnerId = programInfo.ProgramIdValue; } - rc = SaveDataAccessibilityChecker.CheckCreate(in attribute, in creationInfo, programInfo, + rc = SaveDataAccessibilityChecker.CheckCreate(in attribute, in tempCreationInfo, programInfo, programInfo.ProgramId); if (rc.IsFailure()) return rc; // Static system saves don't usually have meta files - SaveDataMetaInfo dataMetaInfo = default; + SaveDataMetaInfo metaInfo = default; Optional hashSalt = default; - return CreateSaveDataFileSystemCore(in attribute, in creationInfo, in dataMetaInfo, in hashSalt); + return CreateSaveDataFileSystemCore(in attribute, in tempCreationInfo, in metaInfo, in hashSalt); } public Result ExtendSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, long dataSize, diff --git a/tests/LibHac.Tests/Fs/FileSystemClientTests/ShimTests/SaveDataManagement.cs b/tests/LibHac.Tests/Fs/FileSystemClientTests/ShimTests/SaveDataManagement.cs index edd88124..dd5d748c 100644 --- a/tests/LibHac.Tests/Fs/FileSystemClientTests/ShimTests/SaveDataManagement.cs +++ b/tests/LibHac.Tests/Fs/FileSystemClientTests/ShimTests/SaveDataManagement.cs @@ -141,6 +141,48 @@ namespace LibHac.Tests.Fs.FileSystemClientTests.ShimTests Assert.Equal(SaveDataState.Normal, info[0].State); } + [Theory] + [InlineData(AccessControlBits.Bits.SystemSaveData)] + [InlineData(AccessControlBits.Bits.None)] + public void CreateSystemSaveData_HasBuiltInSystemPermission_SaveIsCreatedInSystem(AccessControlBits.Bits permissions) + { + ulong saveId = 0x8000000001234000; + + Horizon hos = FileSystemServerFactory.CreateHorizonServer(); + + var mainProgramId = new ProgramId(0x123456); + + HorizonClient client = hos.CreateHorizonClient(new ProgramLocation(mainProgramId, StorageId.BuiltInSystem), + permissions); + + HorizonClient privilegedClient = hos.CreatePrivilegedHorizonClient(); + + // Create the save + if (permissions.HasFlag(AccessControlBits.Bits.SystemSaveData)) + { + Assert.Success(client.Fs.CreateSystemSaveData(saveId, 0x1000, 0x1000, SaveDataFlags.None)); + } + else + { + // Creation should fail if we don't have the right permissions. + Assert.Failure(client.Fs.CreateSystemSaveData(saveId, 0x1000, 0x1000, SaveDataFlags.None)); + return; + } + + // Make sure it was placed in the System save space with the right info. + Assert.Success(privilegedClient.Fs.OpenSaveDataIterator(out SaveDataIterator iterator, SaveDataSpaceId.System)); + + var info = new SaveDataInfo[2]; + Assert.Success(iterator.ReadSaveDataInfo(out long entriesRead, info)); + + Assert.Equal(1, entriesRead); + Assert.Equal(SaveDataType.System, info[0].Type); + Assert.Equal(SaveDataSpaceId.System, info[0].SpaceId); + Assert.Equal(saveId, info[0].StaticSaveDataId); + Assert.Equal(saveId, info[0].SaveDataId); + Assert.Equal(SaveDataState.Normal, info[0].State); + } + [Fact] public void CreateSaveData_DoesNotExist_SaveIsCreated() {