mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-02 06:44:45 +00:00
Merge pull request #8765 from unknownbrackets/ramcache
Fix buffer overflow in cache ISO in RAM feature
This commit is contained in:
commit
8bd7e28355
@ -90,13 +90,13 @@ size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RamCachingFileLoader::InitCache() {
|
void RamCachingFileLoader::InitCache() {
|
||||||
cache_ = (u8 *)malloc(filesize_);
|
lock_guard guard(blocksMutex_);
|
||||||
|
u32 blockCount = (u32)((filesize_ + BLOCK_SIZE - 1) >> BLOCK_SHIFT);
|
||||||
|
// Overallocate for the last block.
|
||||||
|
cache_ = (u8 *)malloc((size_t)blockCount << BLOCK_SHIFT);
|
||||||
if (cache_ == nullptr) {
|
if (cache_ == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_guard guard(blocksMutex_);
|
|
||||||
u32 blockCount = (u32)((filesize_ + BLOCK_SIZE - 1) >> BLOCK_SHIFT);
|
|
||||||
aheadRemaining_ = blockCount;
|
aheadRemaining_ = blockCount;
|
||||||
blocks_.resize(blockCount);
|
blocks_.resize(blockCount);
|
||||||
}
|
}
|
||||||
@ -133,6 +133,15 @@ size_t RamCachingFileLoader::ReadFromCache(s64 pos, size_t bytes, void *data) {
|
|||||||
size_t offset = (size_t)(pos - (cacheStartPos << BLOCK_SHIFT));
|
size_t offset = (size_t)(pos - (cacheStartPos << BLOCK_SHIFT));
|
||||||
u8 *p = (u8 *)data;
|
u8 *p = (u8 *)data;
|
||||||
|
|
||||||
|
// Clamp bytes to what's actually available.
|
||||||
|
if (pos + bytes > filesize_) {
|
||||||
|
// Should've been caught above, but just in case.
|
||||||
|
if (pos >= filesize_) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bytes = filesize_ - pos;
|
||||||
|
}
|
||||||
|
|
||||||
lock_guard guard(blocksMutex_);
|
lock_guard guard(blocksMutex_);
|
||||||
for (s64 i = cacheStartPos; i <= cacheEndPos; ++i) {
|
for (s64 i = cacheStartPos; i <= cacheEndPos; ++i) {
|
||||||
if (blocks_[i] == 0) {
|
if (blocks_[i] == 0) {
|
||||||
@ -172,15 +181,17 @@ void RamCachingFileLoader::SaveIntoCache(s64 pos, size_t bytes) {
|
|||||||
|
|
||||||
backendMutex_.lock();
|
backendMutex_.lock();
|
||||||
s64 cacheFilePos = cacheStartPos << BLOCK_SHIFT;
|
s64 cacheFilePos = cacheStartPos << BLOCK_SHIFT;
|
||||||
backend_->ReadAt(cacheFilePos, blocksToRead << BLOCK_SHIFT, &cache_[cacheFilePos]);
|
size_t bytesRead = backend_->ReadAt(cacheFilePos, blocksToRead << BLOCK_SHIFT, &cache_[cacheFilePos]);
|
||||||
backendMutex_.unlock();
|
backendMutex_.unlock();
|
||||||
|
|
||||||
|
// In case there was an error, let's not mark blocks that failed to read as read.
|
||||||
|
u32 blocksActuallyRead = (u32)((bytesRead + BLOCK_SIZE - 1) >> BLOCK_SHIFT);
|
||||||
{
|
{
|
||||||
lock_guard guard(blocksMutex_);
|
lock_guard guard(blocksMutex_);
|
||||||
|
|
||||||
// In case they were simultaneously read.
|
// In case they were simultaneously read.
|
||||||
u32 blocksRead = 0;
|
u32 blocksRead = 0;
|
||||||
for (size_t i = 0; i < blocksToRead; ++i) {
|
for (size_t i = 0; i < blocksActuallyRead; ++i) {
|
||||||
if (blocks_[cacheStartPos + i] == 0) {
|
if (blocks_[cacheStartPos + i] == 0) {
|
||||||
blocks_[cacheStartPos + i] = 1;
|
blocks_[cacheStartPos + i] = 1;
|
||||||
++blocksRead;
|
++blocksRead;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user