fix(kernel): finish Posix -1/errno for file ops and open EACCES (#567)

Map UnauthorizedAccess on open to PERMISSION_DENIED and route Posix
lseek/pread/pwrite/rename/etc failures through PosixFailure so libc-style
callers get RAX=-1 plus TLS errno, matching open/read/write.
This commit is contained in:
Radu Ursache
2026-07-23 15:32:56 +03:00
committed by GitHub
parent d7bd814fb9
commit 956da769a3
3 changed files with 185 additions and 13 deletions
@@ -46,7 +46,13 @@ public static partial class KernelMemoryCompatExports
[SysAbiExport(Nid = "ezv-RSBNKqI", ExportName = "pread",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
public static int PosixPread(CpuContext ctx) => KernelPreadCore(ctx);
public static int PosixPread(CpuContext ctx)
{
var result = KernelPreadCore(ctx);
return result == (int)OrbisGen2Result.ORBIS_GEN2_OK
? 0
: PosixFailure(ctx, result, notFoundErrno: Ebadf);
}
[SysAbiExport(Nid = "+r3rMFwItV4", ExportName = "sceKernelPread",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
@@ -97,7 +103,13 @@ public static partial class KernelMemoryCompatExports
[SysAbiExport(Nid = "C2kJ-byS5rM", ExportName = "pwrite",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
public static int PosixPwrite(CpuContext ctx) => KernelPwriteCore(ctx);
public static int PosixPwrite(CpuContext ctx)
{
var result = KernelPwriteCore(ctx);
return result == (int)OrbisGen2Result.ORBIS_GEN2_OK
? 0
: PosixFailure(ctx, result, notFoundErrno: Ebadf);
}
[SysAbiExport(Nid = "nKWi-N2HBV4", ExportName = "sceKernelPwrite",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
@@ -149,7 +161,13 @@ public static partial class KernelMemoryCompatExports
[SysAbiExport(Nid = "juWbTNM+8hw", ExportName = "fsync",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
public static int PosixFsync(CpuContext ctx) => KernelFsyncCore(ctx);
public static int PosixFsync(CpuContext ctx)
{
var result = KernelFsyncCore(ctx);
return result == (int)OrbisGen2Result.ORBIS_GEN2_OK
? 0
: PosixFailure(ctx, result, notFoundErrno: Ebadf);
}
[SysAbiExport(Nid = "fTx66l5iWIA", ExportName = "sceKernelFsync",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
@@ -157,7 +175,13 @@ public static partial class KernelMemoryCompatExports
[SysAbiExport(Nid = "KIbJFQ0I1Cg", ExportName = "fdatasync",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
public static int PosixFdatasync(CpuContext ctx) => KernelFsyncCore(ctx);
public static int PosixFdatasync(CpuContext ctx)
{
var result = KernelFsyncCore(ctx);
return result == (int)OrbisGen2Result.ORBIS_GEN2_OK
? 0
: PosixFailure(ctx, result, notFoundErrno: Ebadf);
}
[SysAbiExport(Nid = "30Rh4ixbKy4", ExportName = "sceKernelFdatasync",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
@@ -210,7 +234,13 @@ public static partial class KernelMemoryCompatExports
[SysAbiExport(Nid = "ih4CD9-gghM", ExportName = "ftruncate",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
public static int PosixFtruncate(CpuContext ctx) => KernelFtruncateCore(ctx);
public static int PosixFtruncate(CpuContext ctx)
{
var result = KernelFtruncateCore(ctx);
return result == (int)OrbisGen2Result.ORBIS_GEN2_OK
? 0
: PosixFailure(ctx, result, notFoundErrno: Ebadf);
}
[SysAbiExport(Nid = "VW3TVZiM4-E", ExportName = "sceKernelFtruncate",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
@@ -246,7 +276,13 @@ public static partial class KernelMemoryCompatExports
[SysAbiExport(Nid = "ayrtszI7GBg", ExportName = "truncate",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
public static int PosixTruncate(CpuContext ctx) => KernelTruncateCore(ctx);
public static int PosixTruncate(CpuContext ctx)
{
var result = KernelTruncateCore(ctx);
return result == (int)OrbisGen2Result.ORBIS_GEN2_OK
? 0
: PosixFailure(ctx, result);
}
[SysAbiExport(Nid = "WlyEA-sLDf0", ExportName = "sceKernelTruncate",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
@@ -294,7 +330,13 @@ public static partial class KernelMemoryCompatExports
[SysAbiExport(Nid = "NN01qLRhiqU", ExportName = "rename",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
public static int PosixRename(CpuContext ctx) => KernelRenameCore(ctx);
public static int PosixRename(CpuContext ctx)
{
var result = KernelRenameCore(ctx);
return result == (int)OrbisGen2Result.ORBIS_GEN2_OK
? 0
: PosixFailure(ctx, result);
}
[SysAbiExport(Nid = "52NcYU9+lEo", ExportName = "sceKernelRename",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
@@ -363,7 +405,10 @@ public static partial class KernelMemoryCompatExports
{
if (!_openFiles.TryGetValue(fd, out var stream))
{
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND;
return PosixFailure(
ctx,
(int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND,
notFoundErrno: Ebadf);
}
// POSIX dup shares the open file description (and offset), which is
@@ -386,7 +431,10 @@ public static partial class KernelMemoryCompatExports
{
if (!_openFiles.TryGetValue(oldFd, out var stream))
{
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND;
return PosixFailure(
ctx,
(int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND,
notFoundErrno: Ebadf);
}
if (oldFd == newFd)
@@ -412,7 +460,13 @@ public static partial class KernelMemoryCompatExports
[SysAbiExport(Nid = "8nY19bKoiZk", ExportName = "fcntl",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
public static int PosixFcntl(CpuContext ctx) => KernelFcntlCore(ctx);
public static int PosixFcntl(CpuContext ctx)
{
var result = KernelFcntlCore(ctx);
return result == (int)OrbisGen2Result.ORBIS_GEN2_OK
? 0
: PosixFailure(ctx, result, notFoundErrno: Ebadf);
}
[SysAbiExport(Nid = "SoZkxZkCHaw", ExportName = "sceKernelFcntl",
Target = Generation.Gen4 | Generation.Gen5, LibraryName = "libKernel")]
@@ -1558,7 +1558,7 @@ public static partial class KernelMemoryCompatExports
{
LogOpenTrace($"_open fail path='{guestPath}' host='{hostPath}' flags=0x{flags:X8} ex={ex.GetType().Name}: {ex.Message}");
return ex is UnauthorizedAccessException
? (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT
? (int)OrbisGen2Result.ORBIS_GEN2_ERROR_PERMISSION_DENIED
: (int)OrbisGen2Result.ORBIS_GEN2_ERROR_NOT_FOUND;
}
}
@@ -2228,8 +2228,7 @@ public static partial class KernelMemoryCompatExports
if (result != OrbisGen2Result.ORBIS_GEN2_OK)
{
ctx[CpuRegister.Rax] = ulong.MaxValue;
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
return PosixFailure(ctx, (int)result, notFoundErrno: Ebadf);
}
ctx[CpuRegister.Rax] = unchecked((ulong)position);