From 373d0ea7f0cbe7c343a764293ed39c7b489e5d83 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Thu, 1 Oct 2026 15:22:00 +0300 Subject: [PATCH] rsx: Add bounds checking to transform constant loading --- rpcs3/Emu/RSX/NV47/HW/nv4097.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp index 313daf12c2..b961b1db2f 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv4097.cpp @@ -27,8 +27,10 @@ namespace rsx const u32 constant_id = index / 4; const u8 subreg = index % 4; const u32 load = REGS(ctx)->transform_constant_load(); + const u32 load_offset = load + constant_id; - REGS(ctx)->transform_constants[load + constant_id][subreg] = arg; + ensure(load_offset < 468); + REGS(ctx)->transform_constants[load_offset][subreg] = arg; } void set_transform_constant::batch_decode(context* ctx, u32 reg, const std::span& args, const std::function& notify) @@ -37,12 +39,14 @@ namespace rsx const u32 constant_id = index / 4; const u8 subreg = index % 4; const u32 load = REGS(ctx)->transform_constant_load(); + const u32 load_offset = load + constant_id; + const u32 last_constant_id = ((reg + ::size32(args) + 3) - NV4097_SET_TRANSFORM_CONSTANT) / 4; // Aligned div - auto dst = ®S(ctx)->transform_constants[load + constant_id][subreg]; + ensure(load < 468 && (load + last_constant_id) <= 468); + auto dst = ®S(ctx)->transform_constants[load_offset][subreg]; copy_data_swap_u32(dst, args.data(), ::size32(args)); // Notify - const u32 last_constant_id = ((reg + ::size32(args) + 3) - NV4097_SET_TRANSFORM_CONSTANT) / 4; // Aligned div const u32 load_index = load + constant_id; const u32 load_count = last_constant_id - constant_id; @@ -66,12 +70,12 @@ namespace rsx // Get limit imposed by FIFO PUT (if put is behind get it will result in a number ignored by min) const u32 fifo_read_limit = static_cast(((RSX(ctx)->ctrl->put & ~3ull) - (RSX(ctx)->fifo_ctrl->get_pos())) / 4); - const u32 count = std::min({ fifo_args_cnt, fifo_read_limit, method_range }); - const u32 load = REGS(ctx)->transform_constant_load(); + ensure(load + constant_id < 468); u32 rcount = count; + if (const u32 max = (load + constant_id) * 4 + count + subreg, limit = 468 * 4; max > limit) { // Ignore addresses outside the usable [0, 467] range