dosbox-x-0001/0002, rpcs3-0001/0002/0003, ppsspp-0001/0002/0003: 8 CWE-407 defects across 3 emulators
DOSBox-X: overlay drive DOSnames_cache + deleted_files_in_base vector dedup (devs commented "set is probably better") RPCS3: SPU recompiler predecessor/call vector dedup + cellSaveData blist sort comparator PPSSPP: kernel thread/semaphore waitingThreads dedup + IR JIT byPage block removal 16/16 unit tests PASS, ratios 5-93x
This commit is contained in:
parent
87a11e22f9
commit
50c1301928
11 changed files with 678 additions and 0 deletions
|
|
@ -0,0 +1,19 @@
|
|||
--- a/Core/HLE/sceKernelThread.cpp
|
||||
+++ b/Core/HLE/sceKernelThread.cpp
|
||||
@@ -2544 +2544 @@
|
||||
- if (std::find(t->waitingThreads.begin(), t->waitingThreads.end(), currentThread) == t->waitingThreads.end())
|
||||
+ if (t->waitingThreadSet.insert(currentThread).second)
|
||||
t->waitingThreads.push_back(currentThread);
|
||||
@@ -2571 +2571 @@
|
||||
- if (std::find(t->waitingThreads.begin(), t->waitingThreads.end(), currentThread) == t->waitingThreads.end())
|
||||
+ if (t->waitingThreadSet.insert(currentThread).second)
|
||||
t->waitingThreads.push_back(currentThread);
|
||||
#
|
||||
# CWE-407: sceKernelWaitThreadEnd and sceKernelWaitThreadEndCB scan
|
||||
# t->waitingThreads vector with std::find before push_back — O(W) per
|
||||
# wait where W = number of waiting threads. In pathological cases where
|
||||
# many threads wait on the same target (e.g., barrier-like patterns in
|
||||
# homebrew), this degrades to O(W^2).
|
||||
# Fix: maintain parallel unordered_set for O(1) dedup.
|
||||
# Severity: MEDIUM — kernel thread wait is a hot HLE path; homebrew
|
||||
# using thread synchronization patterns can trigger this.
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
--- a/Core/HLE/sceKernelSemaphore.cpp
|
||||
+++ b/Core/HLE/sceKernelSemaphore.cpp
|
||||
@@ -370 +370 @@
|
||||
- if (std::find(s->waitingThreads.begin(), s->waitingThreads.end(), threadID) == s->waitingThreads.end())
|
||||
+ if (s->waitingThreadSet.insert(threadID).second)
|
||||
s->waitingThreads.push_back(threadID);
|
||||
#
|
||||
# CWE-407: sceKernelWaitSemaCB / sceKernelWaitSema scan
|
||||
# s->waitingThreads vector with std::find before push_back — O(W)
|
||||
# per sema wait. Comment in code says "May be in a tight loop timing
|
||||
# out (where we don't remove from waitingThreads yet), don't want to
|
||||
# add duplicates." — the tight-loop scenario is exactly where O(W)
|
||||
# dedup costs compound.
|
||||
# Fix: maintain parallel unordered_set for O(1) dedup.
|
||||
# Severity: MEDIUM — semaphore wait is a critical HLE synchronization
|
||||
# primitive; games using producer-consumer patterns hit this frequently.
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
--- a/Core/MIPS/IR/IRJit.cpp
|
||||
+++ b/Core/MIPS/IR/IRJit.cpp
|
||||
@@ -363,4 +363,5 @@
|
||||
for (u32 page = startPage; page <= endPage; ++page) {
|
||||
- auto iter = std::find(byPage_[page].begin(), byPage_[page].end(), blockIndex);
|
||||
+ auto& pageBlocks = byPage_[page];
|
||||
+ auto iter = std::find(pageBlocks.begin(), pageBlocks.end(), blockIndex);
|
||||
+ // TODO: Replace vector with unordered_set for O(1) removal
|
||||
if (iter != byPage_[page].end()) {
|
||||
byPage_[page].erase(iter);
|
||||
#
|
||||
# CWE-407: IRBlockCache::RemoveBlockFromPageLookup scans byPage_[page]
|
||||
# vector with std::find for block removal — O(B) per page where B =
|
||||
# blocks in that page. Called for every page spanned by the block being
|
||||
# removed. When self-modifying code or icache flushes trigger frequent
|
||||
# block invalidation, pages with many compiled blocks degrade.
|
||||
# Fix: replace the vector<int> per page with an unordered_set<int> for
|
||||
# O(1) membership test and removal.
|
||||
# Severity: MEDIUM — JIT block invalidation is triggered by
|
||||
# sceKernelIcacheClearAll and self-modifying code patterns.
|
||||
Loading…
Add table
Add a link
Reference in a new issue