mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add permission checks to DeleteSaveDataFileSystem
This commit is contained in:
parent
1f25b87d20
commit
4552a2d94f
4 changed files with 38 additions and 20 deletions
|
@ -190,17 +190,27 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
private Result DeleteSaveDataFileSystemImpl(SaveDataSpaceId spaceId, ulong saveDataId)
|
private Result DeleteSaveDataFileSystemImpl(SaveDataSpaceId spaceId, ulong saveDataId)
|
||||||
{
|
{
|
||||||
Result rc = OpenSaveDataIndexerAccessor(out SaveDataIndexerAccessor accessor, spaceId);
|
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
using (accessor)
|
SaveDataIndexerAccessor accessor = null;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
|
SaveDataType saveType;
|
||||||
|
|
||||||
if (saveDataId == FileSystemServer.SaveIndexerId)
|
if (saveDataId == FileSystemServer.SaveIndexerId)
|
||||||
{
|
{
|
||||||
// missing: This save can only be deleted by the FS process itself
|
if (!IsCurrentProcess(CurrentProcess))
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
|
|
||||||
|
saveType = SaveDataType.System;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
rc = OpenSaveDataIndexerAccessor(out accessor, spaceId);
|
||||||
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
if (spaceId != SaveDataSpaceId.ProperSystem && spaceId != SaveDataSpaceId.SafeMode)
|
if (spaceId != SaveDataSpaceId.ProperSystem && spaceId != SaveDataSpaceId.SafeMode)
|
||||||
{
|
{
|
||||||
rc = accessor.Indexer.GetValue(out SaveDataIndexerValue value, saveDataId);
|
rc = accessor.Indexer.GetValue(out SaveDataIndexerValue value, saveDataId);
|
||||||
|
@ -214,13 +224,17 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
if (key.Type == SaveDataType.System || key.Type == SaveDataType.SystemBcat)
|
if (key.Type == SaveDataType.System || key.Type == SaveDataType.SystemBcat)
|
||||||
{
|
{
|
||||||
// Check if permissions allow deleting system save data
|
if (!programInfo.AccessControl.CanCall(OperationType.DeleteSystemSaveData))
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check if permissions allow deleting save data
|
if (!programInfo.AccessControl.CanCall(OperationType.DeleteSaveData))
|
||||||
|
return ResultFs.PermissionDenied.Log();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveType = key.Type;
|
||||||
|
|
||||||
rc = accessor.Indexer.SetState(saveDataId, SaveDataState.Creating);
|
rc = accessor.Indexer.SetState(saveDataId, SaveDataState.Creating);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
@ -228,11 +242,12 @@ namespace LibHac.FsSrv
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = DeleteSaveDataFileSystemImpl2(spaceId, saveDataId);
|
rc = DeleteSaveDataFileSystemImpl2(spaceId, saveDataId, saveType, false);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
if (saveDataId != FileSystemServer.SaveIndexerId)
|
if (saveDataId != FileSystemServer.SaveIndexerId)
|
||||||
{
|
{
|
||||||
|
// ReSharper disable once PossibleNullReferenceException
|
||||||
rc = accessor.Indexer.Delete(saveDataId);
|
rc = accessor.Indexer.Delete(saveDataId);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
@ -242,12 +257,14 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
finally { accessor?.Dispose(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result DeleteSaveDataFileSystemImpl2(SaveDataSpaceId spaceId, ulong saveDataId)
|
// ReSharper disable once UnusedParameter.Local
|
||||||
|
private Result DeleteSaveDataFileSystemImpl2(SaveDataSpaceId spaceId, ulong saveDataId, SaveDataType type, bool shouldWipe)
|
||||||
{
|
{
|
||||||
// missing: Check extra data flags for this value. Bit 3
|
// missing: Check extra data flags for this value. Bit 3
|
||||||
bool doSecureDelete = false;
|
bool doSecureDelete = shouldWipe;
|
||||||
|
|
||||||
Result rc = FsProxyCore.DeleteSaveDataMetaFiles(saveDataId, spaceId);
|
Result rc = FsProxyCore.DeleteSaveDataMetaFiles(saveDataId, spaceId);
|
||||||
if (rc.IsFailure() && !ResultFs.PathNotFound.Includes(rc))
|
if (rc.IsFailure() && !ResultFs.PathNotFound.Includes(rc))
|
||||||
|
@ -275,7 +292,6 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
using (accessor)
|
using (accessor)
|
||||||
{
|
{
|
||||||
|
|
||||||
rc = accessor.Indexer.GetValue(out SaveDataIndexerValue value, saveDataId);
|
rc = accessor.Indexer.GetValue(out SaveDataIndexerValue value, saveDataId);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
|
@ -326,6 +342,8 @@ namespace LibHac.FsSrv
|
||||||
|
|
||||||
SaveDataIndexerAccessor accessor = null;
|
SaveDataIndexerAccessor accessor = null;
|
||||||
|
|
||||||
|
// Missing permission checks
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (attribute.StaticSaveDataId == FileSystemServer.SaveIndexerId)
|
if (attribute.StaticSaveDataId == FileSystemServer.SaveIndexerId)
|
||||||
|
@ -399,7 +417,7 @@ namespace LibHac.FsSrv
|
||||||
{
|
{
|
||||||
if (!ResultFs.PathAlreadyExists.Includes(rc)) return rc;
|
if (!ResultFs.PathAlreadyExists.Includes(rc)) return rc;
|
||||||
|
|
||||||
rc = DeleteSaveDataFileSystemImpl2(creationInfo.SpaceId, saveDataId);
|
rc = DeleteSaveDataFileSystemImpl2(creationInfo.SpaceId, saveDataId, attribute.Type, false);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
rc = FsProxyCore.CreateSaveDataFileSystem(saveDataId, ref attribute, ref creationInfo, SaveDataRootPath,
|
rc = FsProxyCore.CreateSaveDataFileSystem(saveDataId, ref attribute, ref creationInfo, SaveDataRootPath,
|
||||||
|
@ -455,7 +473,7 @@ namespace LibHac.FsSrv
|
||||||
// Revert changes if an error happened in the middle of creation
|
// Revert changes if an error happened in the middle of creation
|
||||||
if (isDeleteNeeded)
|
if (isDeleteNeeded)
|
||||||
{
|
{
|
||||||
DeleteSaveDataFileSystemImpl2(creationInfo.SpaceId, saveDataId).IgnoreResult();
|
DeleteSaveDataFileSystemImpl2(creationInfo.SpaceId, saveDataId, attribute.Type, false).IgnoreResult();
|
||||||
|
|
||||||
if (accessor != null && saveDataId != FileSystemServer.SaveIndexerId)
|
if (accessor != null && saveDataId != FileSystemServer.SaveIndexerId)
|
||||||
{
|
{
|
||||||
|
@ -1253,6 +1271,13 @@ namespace LibHac.FsSrv
|
||||||
return FsProxyCore.ProgramRegistry.GetProgramInfo(out programInfo, CurrentProcess);
|
return FsProxyCore.ProgramRegistry.GetProgramInfo(out programInfo, CurrentProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool IsCurrentProcess(ulong processId)
|
||||||
|
{
|
||||||
|
ulong currentId = Hos.Os.GetCurrentProcessId().Value;
|
||||||
|
|
||||||
|
return processId == currentId;
|
||||||
|
}
|
||||||
|
|
||||||
private static bool IsSystemSaveDataId(ulong id)
|
private static bool IsSystemSaveDataId(ulong id)
|
||||||
{
|
{
|
||||||
return (long)id < 0;
|
return (long)id < 0;
|
||||||
|
|
|
@ -96,13 +96,6 @@ namespace LibHac.FsSrv
|
||||||
return new ProgramRegistryImpl(FsProxyCore.Config.ProgramRegistryServiceImpl);
|
return new ProgramRegistryImpl(FsProxyCore.Config.ProgramRegistryServiceImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool IsCurrentProcess(ulong processId)
|
|
||||||
{
|
|
||||||
ulong currentId = Hos.Os.GetCurrentProcessId().Value;
|
|
||||||
|
|
||||||
return processId == currentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FileSystemProxyService : IServiceObject
|
private class FileSystemProxyService : IServiceObject
|
||||||
{
|
{
|
||||||
private readonly FileSystemServer _server;
|
private readonly FileSystemServer _server;
|
||||||
|
|
|
@ -167,7 +167,7 @@ namespace LibHac.FsSrv.Impl
|
||||||
ReadOnlySpan<byte> accessControlDescriptor)
|
ReadOnlySpan<byte> accessControlDescriptor)
|
||||||
{
|
{
|
||||||
ProcessId = 0;
|
ProcessId = 0;
|
||||||
AccessControl = new AccessControl(fsServer, accessControlData, accessControlDescriptor);
|
AccessControl = new AccessControl(fsServer, accessControlData, accessControlDescriptor, ulong.MaxValue);
|
||||||
ProgramId = default;
|
ProgramId = default;
|
||||||
StorageId = 0;
|
StorageId = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace LibHac.Tests.Fs.FileSystemClientTests
|
||||||
|
|
||||||
var horizon = new Horizon(new StopWatchTimeSpanGenerator(), config);
|
var horizon = new Horizon(new StopWatchTimeSpanGenerator(), config);
|
||||||
|
|
||||||
HorizonClient horizonClient = horizon.CreateHorizonClient();
|
HorizonClient horizonClient = horizon.CreatePrivilegedHorizonClient();
|
||||||
|
|
||||||
return horizonClient.Fs;
|
return horizonClient.Fs;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue