aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuck912 <350528965+Duck912@users.noreply.github.com>2026-11-03 12:56:43 -0500
committerDuck912 <350528965+Duck912@users.noreply.github.com>2026-11-03 13:06:59 -0500
commitf9d0c802e8e4e71644bf4b7e6cceca8e6df22464 (patch)
tree74ab11bfe249617baa7f7c5b1f729eeb7538ba3e
parentf4f076fe447b2ddc158fcc12ee81ed2af2aecad7 (diff)
yuzu: bound the zip directory reads in the DLSS download
The central-directory parser trusted each entry's name, extra and comment lengths and the Zip64 extra field's length, so a malformed directory could make it read past the downloaded buffer. The data comes from NVIDIA's GitHub release over TLS and the saved files are signature-checked, so the risk is low. Stop with an error when an entry runs past the directory, and read Zip64 fields only inside their record. Found by CodeRabbit review. Assisted-by: Claude Opus 5.5 (implementation) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
-rw-r--r--src/yuzu/configuration/nvidia_dlss_panel.cpp9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/yuzu/configuration/nvidia_dlss_panel.cpp b/src/yuzu/configuration/nvidia_dlss_panel.cpp
index 2329693a03..040ea90557 100644
--- a/src/yuzu/configuration/nvidia_dlss_panel.cpp
+++ b/src/yuzu/configuration/nvidia_dlss_panel.cpp
@@ -166,16 +166,21 @@ public:
.size = U32(*directory, at + 24),
.offset = U32(*directory, at + 42),
};
+ const size_t extra_end = at + 46 + name_length + extra_length;
+ if (extra_end + comment_length > directory->size()) {
+ error = "bad zip directory";
+ return false;
+ }
const std::string name = directory->substr(at + 46, name_length);
// Zip64 sizes and offset, in this order, for the fields that overflowed.
- const size_t extra_end = at + 46 + name_length + extra_length;
for (size_t extra = at + 46 + name_length; extra + 4 <= extra_end;) {
const u16 id = U16(*directory, extra);
const u16 length = U16(*directory, extra + 2);
+ const size_t record_end = std::min<size_t>(extra + 4 + length, extra_end);
if (id == 0x0001) {
size_t field = extra + 4;
for (u64* value : {&entry.size, &entry.compressed, &entry.offset}) {
- if (*value == 0xFFFFFFFF) {
+ if (*value == 0xFFFFFFFF && field + 8 <= record_end) {
*value = U64(*directory, field);
field += 8;
}