fix(libkernel): bound scalar writes to anonymous shared memory

This commit is contained in:
Kang, Harry Zixuan authored and Daniele Giovane committed 2026-10-24 22:37:11 +02:00
1 parent f302e49837
commit c5447f8aaf
3 files changed
+11 -3

No files matched your search

@@ -14,6 +14,9 @@ std::int64_t WriteSharedMemory_nid_no_patch(int descriptor, const void* buffer,
std::int64_t PwriteSharedMemory_nid_no_patch(int descriptor, const void* buffer, std::size_t size, std::int64_t offset);
std::int64_t SeekSharedMemory_nid_no_patch(int descriptor, std::int64_t offset, int whence);
int TruncateSharedMemory_nid_no_patch(int descriptor, std::int64_t length);
#ifdef _WIN32
bool LimitSharedMemoryWrite_nid_no_patch(int descriptor, std::size_t& size, std::int64_t offset);
#endif
#ifndef _WIN32
std::int64_t WritevSharedMemory_nid_no_patch(int descriptor, const struct iovec* vectors, int count);
std::int64_t PwritevSharedMemory_nid_no_patch(int descriptor, const struct iovec* vectors, int count, std::int64_t offset);
@@ -74,6 +74,11 @@ static int NativeWrite(int fd, const void* buf, std::size_t n) {
throw std::runtime_error("sceKernelWrite: nbytes exceeds platform limit");
}
const auto positioned = File::LockPositionedTransfer(fd);
if (File::HasFixedSizeWrites(fd)) {
const auto position = ::_lseeki64(fd, 0, SEEK_CUR);
if (position < 0 || !File::LimitSharedMemoryWrite_nid_no_patch(fd, n, position)) return -1;
if (n == 0) return 0;
}
const auto shared = File::WriteSharedMemory_nid_no_patch(fd, buf, n);
if (shared != -2) return static_cast<int>(shared);
if (File::Appends(fd)) {
+3 -3
View File
@@ -245,7 +245,7 @@ void File::SharePositionedTransfer(int from, int to) {
if (!source) source = std::make_shared<PositionedLock>();
g_positionedLocks[to] = source;
}
static bool LimitSharedMemoryWrite(int descriptor, std::size_t& size, std::int64_t offset) {
bool File::LimitSharedMemoryWrite_nid_no_patch(int descriptor, std::size_t& size, std::int64_t offset) {
if (offset < 0) { errno = EINVAL; return false; }
const auto length = WithoutParameterHandler([descriptor] { return ::_filelengthi64(descriptor); });
if (length < 0) return false;
@@ -258,7 +258,7 @@ static std::int64_t NativePositionedTransfer(int descriptor, void* buf, std::siz
throw std::runtime_error("NativePositioned: nbytes exceeds platform limit");
}
if (write && File::HasFixedSizeWrites(descriptor)) {
if (!LimitSharedMemoryWrite(descriptor, nbytes, offset)) return -1;
if (!File::LimitSharedMemoryWrite_nid_no_patch(descriptor, nbytes, offset)) return -1;
if (nbytes == 0) return 0;
}
const auto handle = reinterpret_cast<HANDLE>(WithoutParameterHandler([descriptor] { return ::_get_osfhandle(descriptor); }));
@@ -325,7 +325,7 @@ static std::int64_t NativeTransferBuffer(int descriptor, void* buf, std::size_t
if (write) {
if (File::HasFixedSizeWrites(descriptor)) {
const auto position = WithoutParameterHandler([descriptor] { return ::_lseeki64(descriptor, 0, SEEK_CUR); });
if (position < 0 || !LimitSharedMemoryWrite(descriptor, nbytes, position)) return -1;
if (position < 0 || !File::LimitSharedMemoryWrite_nid_no_patch(descriptor, nbytes, position)) return -1;
if (nbytes == 0) return 0;
}
const auto result = File::WriteSharedMemory_nid_no_patch(descriptor, buf, nbytes);