fix(systemgesture): validate native pad report input

This commit is contained in:
boykopovar committed 2026-10-21 21:52:42 +03:00
1 parent b27046d68d
commit 91c0535cd7
3 files changed
+15 -12

No files matched your search

+6 -6
View File
@@ -331,14 +331,14 @@ int APS5_VABI sceSystemGestureUpdateAllTouchRecognizer(int32_t gestureHandle) {
return 0;
}
int APS5_VABI sceSystemGestureUpdatePrimitiveTouchRecognizer(int32_t gestureHandle, const void* param) {
int APS5_VABI sceSystemGestureUpdatePrimitiveTouchRecognizer(int32_t gestureHandle, const SystemGestureTouchPadData* input) {
std::lock_guard lock(primitiveTouchMutex);
if (!gestureInitialized) return static_cast<int>(0x80890003);
if (!findGestureContext(gestureHandle)) return SCE_SYSTEM_GESTURE_ERROR_INVALID_HANDLE;
if (!param) return 0;
const auto* input = static_cast<const SystemGestureTouchPadData*>(param);
if (!input->pad_data_buffer || input->report_number <= 0) return 0;
for (std::int32_t i = 0; i < input->report_number; ++i) sampleReport(findGestureContext(gestureHandle)->touches, input->pad_data_buffer[i]);
if (!input || !input->pad_data_buffer) return SCE_SYSTEM_GESTURE_ERROR_INVALID_ARGUMENT;
auto* context = findGestureContext(gestureHandle);
if (!context) return SCE_SYSTEM_GESTURE_ERROR_INVALID_HANDLE;
if (input->report_number < 0 || input->report_number > 1) return SCE_SYSTEM_GESTURE_ERROR_INVALID_ARGUMENT;
if (input->report_number == 1) sampleReport(context->touches, *input->pad_data_buffer);
return 0;
}
+8 -5
View File
@@ -27,7 +27,7 @@ int APS5_VABI sceSystemGestureUpdateTouchRecognizer(std::int32_t, void*);
int APS5_VABI sceSystemGestureUpdateTouchRecognizerRectangle(std::int32_t, void*, const void*);
int APS5_VABI sceSystemGestureResetPrimitiveTouchRecognizer(std::int32_t);
int APS5_VABI sceSystemGestureUpdateAllTouchRecognizer(std::int32_t);
int APS5_VABI sceSystemGestureUpdatePrimitiveTouchRecognizer(std::int32_t, const void*);
int APS5_VABI sceSystemGestureUpdatePrimitiveTouchRecognizer(std::int32_t, const SystemGestureTouchPadData*);
int APS5_VABI sceSystemGestureInitializePrimitiveTouchRecognizer();
int APS5_VABI sceSystemGestureFinalizePrimitiveTouchRecognizer(void);
int APS5_VABI sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(std::int32_t, std::uint16_t, void*);
@@ -191,11 +191,14 @@ static void TestPrimitiveTouchEvents(std::int32_t handle, int invalidArgument, i
Require(sceSystemGestureGetPrimitiveTouchEventByIndex(handle, 2, &event) == indexOutOfArray);
Require(UpdateWithReports(handle + 1, &pair, 1) == invalidHandle);
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle, nullptr) == 0);
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle, nullptr) == invalidArgument);
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 2);
const std::array<PadData, 2> sequence{TouchReport(7000, {{3, 110, 200}}), TouchReport(8000, {{3, 130, 210}})};
Require(UpdateWithReports(handle, sequence.data(), 2) == 0);
Require(UpdateWithReports(handle, sequence.data(), 2) == invalidArgument);
Require(UpdateWithReports(handle, sequence.data(), -1) == invalidArgument);
Require(UpdateWithReports(handle, sequence.data(), 1) == 0);
Require(UpdateWithReports(handle, sequence.data() + 1, 1) == 0);
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 1);
event = SingleEvent(handle);
Require(event.primitive_id == 3);
@@ -261,7 +264,7 @@ int main() {
Require(sceSystemGestureUpdateTouchRecognizerRectangle(handle, &recognizer, &rectangle) == 0);
Require(sceSystemGestureResetPrimitiveTouchRecognizer(handle) == 0);
Require(sceSystemGestureUpdateAllTouchRecognizer(handle) == 0);
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle, nullptr) == 0);
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle, nullptr) == invalidArgument);
Require(sceSystemGestureAppendTouchRecognizer(handle, nullptr) == invalidArgument);
Require(sceSystemGestureUpdateTouchRecognizerRectangle(handle, &recognizer, nullptr) == invalidArgument);
Require(sceSystemGestureAppendTouchRecognizer(handle + 1, &recognizer) == invalidHandle);
@@ -275,7 +278,7 @@ int main() {
Require(sceSystemGestureUpdateTouchRecognizerRectangle(handle + 1, &recognizer, &rectangle) == invalidHandle);
Require(sceSystemGestureResetPrimitiveTouchRecognizer(handle + 1) == invalidHandle);
Require(sceSystemGestureUpdateAllTouchRecognizer(handle + 1) == invalidHandle);
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle + 1, nullptr) == invalidHandle);
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle + 1, nullptr) == invalidArgument);
TestTouchRecognizerInformation(handle, invalidArgument, invalidHandle);
TestPrimitiveTouchEvents(handle, invalidArgument, invalidHandle, indexOutOfArray);
+1 -1
View File
@@ -6,5 +6,5 @@
### Unknown function info
- [Primitive touch events](../../../core/libs/prx/libSceSystemGesture/Export.cpp) (libSceSystemGesture) - `sceSystemGestureUpdatePrimitiveTouchRecognizer` reads the pad reports the title passes in, `{int32 padHandle, int32 reportNumber, const ScePadData* padDataBuffer, 8 reserved bytes}`, as [fpPS4](https://github.com/red-prig/fpPS4/blob/585d06fa7c04698c41272b95a696a14c4180e13e/src/ps4_libscesystemgesture.pas) records `SceSystemGestureTouchPadData`; `padHandle` is not checked and a report of a pad other than the one the title opened is not told apart. The touch states 0 inactive, 1 begin, 2 active and 3 end are the Vita ones in [RPCS3](https://github.com/RPCS3/rpcs3/blob/38c444cfa1dbe152daa63b1703c12172078cd056/rpcs3/Emu/PSP2/Modules/sceSystemGesture.h), whose recognizer, rectangle and primitive event layouts are the ones main already uses, and no public source states the PS5 values. A primitive keeps the touch id the pad reports, its positions are the pad's touchpad coordinates unscaled, `delta_time` and `elapsed_time` come from the reports' own `timestamp`, and `is_updated` is 1 for a primitive whose state or position changed in the update; the console's units, scaling and `is_updated` rule are unverified. An ended touch stays readable as one `end` event until the next report sampled drops it. A null `pInputData`, a null `padDataBuffer` or a `reportNumber` of 0 or less leaves the events unchanged and returns success, an event buffer shorter than the event count reports as many events as it holds, while native update null-pointer and report-count checks are not yet matched
- [Primitive touch events](../../../core/libs/prx/libSceSystemGesture/Export.cpp): pad handles are not validated against native controller information. Begin, active and end states are confirmed, but cancellation state 4, motion thresholds and SDK-dependent duplicate-report handling remain unimplemented. Timing, coordinate conversion and update flags still use the host approximation. Recognizer allocation and native descriptor layouts remain incomplete.
- [sceSystemGestureDebugGetVersion](../../../core/libs/prx/libSceSystemGesture/Export.cpp) (libSceSystemGesture) - its name and NID are in the [PS5 3.20 export inventory](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceSystemGesture.c), but no credible prototype was found. It is declared without parameters solely to resolve known imports; this is not an ABI claim