Skip to content

Commit f1458e3

Browse files
authored
FIX: Fixed potential crash on Mac when using stale references to deleted InputDevice objects (case ISXB-606) (#2009)
* [InputSystem] Fixed potential crash on Mac when using stale references to deleted InputDevice objects (case ISXB-606) o Stale InputDevice references were resulting in random memory accesses. o On Mac some invalid memory accesses (to kernel reserved VM ranges) cannot be caught by the application - the kernel will terminate the process instead. o Add deviceIndex checks when accessing DoubleBuffers front/back buffers to avoid reading random memory. * Change currentStatePtr null check.
1 parent 008f573 commit f1458e3

3 files changed

Lines changed: 31 additions & 5 deletions

File tree

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ however, it has to be formatted properly to pass verification tests.
1515
- Fixed memory leak when the OnScreenStick component was destroyed [ISXB-1070](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1070). Contribution by [LukeUnityDev](https://github.com/LukeUnityDev).
1616
- Fixed Action Maps contextual menu in Action Editor UI that occasionally displays unrelated items.
1717
- Fixed "MissingReferenceException" errors when closing an in-game dropdown field [ISXB-1081](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-1081).
18+
- Fixed potential crash on Mac when using stale references to deleted InputDevice objects [ISXB-606](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-606).
1819

1920
### Changed
2021
- Renamed editor Resources directories to PackageResources to fix package validation warnings.

Packages/com.unity.inputsystem/InputSystem/Controls/InputControl.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,20 @@ internal unsafe ref readonly TValue unprocessedValue
12321232
if (InputUpdate.s_LatestUpdateType.IsEditorUpdate())
12331233
return ref ReadUnprocessedStateInEditor();
12341234
#endif
1235+
// Case ISXB-606
1236+
// If an object reference has the underlying object deleted then a device can go
1237+
// away which means that the underlying state buffers will have been resized.
1238+
//
1239+
// The currentStatePtr accessor uses GetDeviceIndex() to index into the state
1240+
// buffers but this index can then be out of bounds.
1241+
//
1242+
// InputStateBuffers.Get{Front,Back}Buffer() now check for the requested index being
1243+
// in-bounds and return null if not - check that here to avoid null derefence later.
1244+
//
1245+
if (currentStatePtr == null)
1246+
{
1247+
return ref m_UnprocessedCachedValue;
1248+
}
12351249

12361250
if (
12371251
// if feature is disabled we re-evaluate every call

Packages/com.unity.inputsystem/InputSystem/State/InputStateBuffers.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,27 +60,34 @@ internal struct DoubleBuffers
6060
// buffer and [deviceIndex*2+1] is back buffer. Each device
6161
// has its buffers swapped individually with SwapDeviceBuffers().
6262
public void** deviceToBufferMapping;
63+
public int deviceCount;
6364

6465
public bool valid => deviceToBufferMapping != null;
6566

6667
public void SetFrontBuffer(int deviceIndex, void* ptr)
6768
{
68-
deviceToBufferMapping[deviceIndex * 2] = ptr;
69+
if (deviceIndex < deviceCount)
70+
deviceToBufferMapping[deviceIndex * 2] = ptr;
6971
}
7072

7173
public void SetBackBuffer(int deviceIndex, void* ptr)
7274
{
73-
deviceToBufferMapping[deviceIndex * 2 + 1] = ptr;
75+
if (deviceIndex < deviceCount)
76+
deviceToBufferMapping[deviceIndex * 2 + 1] = ptr;
7477
}
7578

7679
public void* GetFrontBuffer(int deviceIndex)
7780
{
78-
return deviceToBufferMapping[deviceIndex * 2];
81+
if (deviceIndex < deviceCount)
82+
return deviceToBufferMapping[deviceIndex * 2];
83+
return null;
7984
}
8085

8186
public void* GetBackBuffer(int deviceIndex)
8287
{
83-
return deviceToBufferMapping[deviceIndex * 2 + 1];
88+
if (deviceIndex < deviceCount)
89+
return deviceToBufferMapping[deviceIndex * 2 + 1];
90+
return null;
8491
}
8592

8693
public void SwapBuffers(int deviceIndex)
@@ -197,7 +204,11 @@ private static DoubleBuffers SetUpDeviceToBufferMappings(int deviceCount, ref by
197204
var mappings = (void**)(bufferPtr + sizePerBuffer * 2); // Put mapping table at end.
198205
bufferPtr += sizePerBuffer * 2 + mappingTableSizePerBuffer;
199206

200-
var buffers = new DoubleBuffers {deviceToBufferMapping = mappings};
207+
var buffers = new DoubleBuffers
208+
{
209+
deviceToBufferMapping = mappings,
210+
deviceCount = deviceCount
211+
};
201212

202213
for (var i = 0; i < deviceCount; ++i)
203214
{

0 commit comments

Comments
 (0)