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)
|
||||
{
|
||||
Result rc = OpenSaveDataIndexerAccessor(out SaveDataIndexerAccessor accessor, spaceId);
|
||||
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
using (accessor)
|
||||
SaveDataIndexerAccessor accessor = null;
|
||||
|
||||
try
|
||||
{
|
||||
SaveDataType saveType;
|
||||
|
||||
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
|
||||
{
|
||||
rc = OpenSaveDataIndexerAccessor(out accessor, spaceId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (spaceId != SaveDataSpaceId.ProperSystem && spaceId != SaveDataSpaceId.SafeMode)
|
||||
{
|
||||
rc = accessor.Indexer.GetValue(out SaveDataIndexerValue value, saveDataId);
|
||||
|
@ -214,13 +224,17 @@ namespace LibHac.FsSrv
|
|||
|
||||
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
|
||||
{
|
||||
// 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);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
|
@ -228,11 +242,12 @@ namespace LibHac.FsSrv
|
|||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
rc = DeleteSaveDataFileSystemImpl2(spaceId, saveDataId);
|
||||
rc = DeleteSaveDataFileSystemImpl2(spaceId, saveDataId, saveType, false);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (saveDataId != FileSystemServer.SaveIndexerId)
|
||||
{
|
||||
// ReSharper disable once PossibleNullReferenceException
|
||||
rc = accessor.Indexer.Delete(saveDataId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
|
@ -242,12 +257,14 @@ namespace LibHac.FsSrv
|
|||
|
||||
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
|
||||
bool doSecureDelete = false;
|
||||
bool doSecureDelete = shouldWipe;
|
||||
|
||||
Result rc = FsProxyCore.DeleteSaveDataMetaFiles(saveDataId, spaceId);
|
||||
if (rc.IsFailure() && !ResultFs.PathNotFound.Includes(rc))
|
||||
|
@ -275,7 +292,6 @@ namespace LibHac.FsSrv
|
|||
|
||||
using (accessor)
|
||||
{
|
||||
|
||||
rc = accessor.Indexer.GetValue(out SaveDataIndexerValue value, saveDataId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
|
@ -326,6 +342,8 @@ namespace LibHac.FsSrv
|
|||
|
||||
SaveDataIndexerAccessor accessor = null;
|
||||
|
||||
// Missing permission checks
|
||||
|
||||
try
|
||||
{
|
||||
if (attribute.StaticSaveDataId == FileSystemServer.SaveIndexerId)
|
||||
|
@ -399,7 +417,7 @@ namespace LibHac.FsSrv
|
|||
{
|
||||
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;
|
||||
|
||||
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
|
||||
if (isDeleteNeeded)
|
||||
{
|
||||
DeleteSaveDataFileSystemImpl2(creationInfo.SpaceId, saveDataId).IgnoreResult();
|
||||
DeleteSaveDataFileSystemImpl2(creationInfo.SpaceId, saveDataId, attribute.Type, false).IgnoreResult();
|
||||
|
||||
if (accessor != null && saveDataId != FileSystemServer.SaveIndexerId)
|
||||
{
|
||||
|
@ -1253,6 +1271,13 @@ namespace LibHac.FsSrv
|
|||
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)
|
||||
{
|
||||
return (long)id < 0;
|
||||
|
|
|
@ -96,13 +96,6 @@ namespace LibHac.FsSrv
|
|||
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 readonly FileSystemServer _server;
|
||||
|
|
|
@ -167,7 +167,7 @@ namespace LibHac.FsSrv.Impl
|
|||
ReadOnlySpan<byte> accessControlDescriptor)
|
||||
{
|
||||
ProcessId = 0;
|
||||
AccessControl = new AccessControl(fsServer, accessControlData, accessControlDescriptor);
|
||||
AccessControl = new AccessControl(fsServer, accessControlData, accessControlDescriptor, ulong.MaxValue);
|
||||
ProgramId = default;
|
||||
StorageId = 0;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace LibHac.Tests.Fs.FileSystemClientTests
|
|||
|
||||
var horizon = new Horizon(new StopWatchTimeSpanGenerator(), config);
|
||||
|
||||
HorizonClient horizonClient = horizon.CreateHorizonClient();
|
||||
HorizonClient horizonClient = horizon.CreatePrivilegedHorizonClient();
|
||||
|
||||
return horizonClient.Fs;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue