summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Morph2020-12-12 06:37:08 -0500
committerGravatar Morph2020-12-12 07:05:38 -0500
commit1c773c0869b95d749613e08301637a0b80f1bbc9 (patch)
treed2a3f0736acd3fd0e043cbeae58ed5b7183344e9
parentMerge pull request #5183 from lioncash/alias2 (diff)
downloadyuzu-1c773c0869b95d749613e08301637a0b80f1bbc9.tar.gz
yuzu-1c773c0869b95d749613e08301637a0b80f1bbc9.tar.xz
yuzu-1c773c0869b95d749613e08301637a0b80f1bbc9.zip
controllers/npad: Validate device handles before use
Some games such as NEKOPARA Vol. 3 send invalid device handles when calling InitializeVibrationDevice. Introduce a check to validate the device handle before use.
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp41
-rw-r--r--src/core/hle/service/hid/controllers/npad.h4
2 files changed, 45 insertions, 0 deletions
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 66c4fe60a..f6a0770bf 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -116,6 +116,31 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
116 } 116 }
117} 117}
118 118
119bool Controller_NPad::IsNpadIdValid(u32 npad_id) {
120 switch (npad_id) {
121 case 0:
122 case 1:
123 case 2:
124 case 3:
125 case 4:
126 case 5:
127 case 6:
128 case 7:
129 case NPAD_UNKNOWN:
130 case NPAD_HANDHELD:
131 return true;
132 default:
133 LOG_ERROR(Service_HID, "Invalid npad id {}", npad_id);
134 return false;
135 }
136}
137
138bool Controller_NPad::IsDeviceHandleValid(const DeviceHandle& device_handle) {
139 return IsNpadIdValid(device_handle.npad_id) &&
140 device_handle.npad_type < NpadType::MaxNpadType &&
141 device_handle.device_index < DeviceIndex::MaxDeviceIndex;
142}
143
119Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {} 144Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
120 145
121Controller_NPad::~Controller_NPad() { 146Controller_NPad::~Controller_NPad() {
@@ -742,6 +767,10 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size
742 767
743void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle, 768void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle,
744 const VibrationValue& vibration_value) { 769 const VibrationValue& vibration_value) {
770 if (!IsDeviceHandleValid(vibration_device_handle)) {
771 return;
772 }
773
745 if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { 774 if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
746 return; 775 return;
747 } 776 }
@@ -798,12 +827,20 @@ void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibrat
798 827
799Controller_NPad::VibrationValue Controller_NPad::GetLastVibration( 828Controller_NPad::VibrationValue Controller_NPad::GetLastVibration(
800 const DeviceHandle& vibration_device_handle) const { 829 const DeviceHandle& vibration_device_handle) const {
830 if (!IsDeviceHandleValid(vibration_device_handle)) {
831 return {};
832 }
833
801 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id); 834 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
802 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 835 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
803 return latest_vibration_values[npad_index][device_index]; 836 return latest_vibration_values[npad_index][device_index];
804} 837}
805 838
806void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_device_handle) { 839void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_device_handle) {
840 if (!IsDeviceHandleValid(vibration_device_handle)) {
841 return;
842 }
843
807 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id); 844 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
808 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 845 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
809 InitializeVibrationDeviceAtIndex(npad_index, device_index); 846 InitializeVibrationDeviceAtIndex(npad_index, device_index);
@@ -824,6 +861,10 @@ void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
824} 861}
825 862
826bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const { 863bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const {
864 if (!IsDeviceHandleValid(vibration_device_handle)) {
865 return false;
866 }
867
827 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id); 868 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
828 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 869 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
829 return vibration_devices_mounted[npad_index][device_index]; 870 return vibration_devices_mounted[npad_index][device_index];
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 96f319294..9fac00231 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -56,12 +56,14 @@ public:
56 JoyconLeft = 6, 56 JoyconLeft = 6,
57 JoyconRight = 7, 57 JoyconRight = 7,
58 Pokeball = 9, 58 Pokeball = 9,
59 MaxNpadType = 10,
59 }; 60 };
60 61
61 enum class DeviceIndex : u8 { 62 enum class DeviceIndex : u8 {
62 Left = 0, 63 Left = 0,
63 Right = 1, 64 Right = 1,
64 None = 2, 65 None = 2,
66 MaxDeviceIndex = 3,
65 }; 67 };
66 68
67 enum class GyroscopeZeroDriftMode : u32 { 69 enum class GyroscopeZeroDriftMode : u32 {
@@ -213,6 +215,8 @@ public:
213 static Settings::ControllerType MapNPadToSettingsType(Controller_NPad::NPadControllerType type); 215 static Settings::ControllerType MapNPadToSettingsType(Controller_NPad::NPadControllerType type);
214 static std::size_t NPadIdToIndex(u32 npad_id); 216 static std::size_t NPadIdToIndex(u32 npad_id);
215 static u32 IndexToNPad(std::size_t index); 217 static u32 IndexToNPad(std::size_t index);
218 static bool IsNpadIdValid(u32 npad_id);
219 static bool IsDeviceHandleValid(const DeviceHandle& device_handle);
216 220
217private: 221private:
218 struct CommonHeader { 222 struct CommonHeader {