Skip to content

Commit 8f8b25c

Browse files
fix: networkanimator does no bounds check when reading parameters (#4090)
* fix Adding bounds check for reading NetworkAnimator parameters. * test Adding a unit test to validate the bounds check. * update adding change log entry * style adding additional comments for clarity on what the test is doing.
1 parent 501ca02 commit 8f8b25c

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
2222

2323
### Fixed
2424

25+
- Issue where `NetworkAnimator` did no bounds check on the parameter index read prior to obtaining a pointer to the location within the array. (#4090)
2526
- Issue where scene migration in a distributed authority session would throw an exception on clients migrating their owned `NetworkObject` instances to a different scene.(#4086)
2627
- Issue where migrating a dynamically spawned or in-scene placed `NetworkObject` into a different scene during awake could result in that spawned instance to not be synchronized. (#4086)
2728
- Issue where a NullReferenceException was thrown when a non-authority failed to spawn a NetworkObject. (#4067)

com.unity.netcode.gameobjects/Runtime/Components/NetworkAnimator.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,13 @@ private unsafe void ReadParameters(FastBufferReader reader)
13771377
while (totalParametersRead < totalParametersToRead)
13781378
{
13791379
ByteUnpacker.ReadValuePacked(reader, out uint parameterIndex);
1380+
1381+
// Do bounds check prior to getting the element as a reference at that index.
1382+
if (parameterIndex >= m_CachedAnimatorParameters.Length)
1383+
{
1384+
NetworkManager.Log.ErrorServer(new Logging.Context(LogLevel.Error, $"[{nameof(NetworkAnimator)}][{name}] Invalid index of {parameterIndex} was received when there are only {m_CachedAnimatorParameters.Length} parameters. Ignoring the remainger of this {nameof(ParametersUpdateMessage)}!"));
1385+
return;
1386+
}
13801387
ref var cacheValue = ref UnsafeUtility.ArrayElementAsRef<AnimatorParamCache>(m_CachedAnimatorParameters.GetUnsafePtr(), (int)parameterIndex);
13811388
var hash = cacheValue.Hash;
13821389
if (cacheValue.Type == AnimationParamEnumWrapper.AnimatorControllerParameterInt)

testproject/Assets/Tests/Runtime/Animation/NetworkAnimatorTests.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
using System.Linq;
44
using NUnit.Framework;
55
using Unity.Netcode;
6+
using Unity.Netcode.Components;
67
using Unity.Netcode.TestHelpers.Runtime;
78
using UnityEngine;
89
using UnityEngine.TestTools;
10+
using static Unity.Netcode.Components.NetworkAnimator;
911

1012

1113
namespace TestProject.RuntimeTests
@@ -336,7 +338,40 @@ public void ParameterExcludedTests()
336338
VerboseDebug($" ------------------ Parameter Test [{m_OwnerShipMode}] Stopping ------------------ ");
337339
}
338340

341+
private unsafe void MockWritingParameters(ref FastBufferWriter writer)
342+
{
343+
writer.Seek(0);
344+
writer.Truncate();
345+
346+
// Write out how many parameter entries to read
347+
BytePacker.WriteValuePacked(writer, (uint)1);
348+
// Write an invalid index level (anything would be invalid with no parameters)
349+
BytePacker.WriteValuePacked(writer, (uint)1000);
350+
// Write some value for the invalid parameter
351+
BytePacker.WriteValuePacked(writer, (uint)10);
352+
}
353+
354+
[Test]
355+
public void ParameterBoundsCheck()
356+
{
357+
var gameObject = new GameObject();
358+
gameObject.AddComponent<NetworkObject>();
359+
var networkAnimator = gameObject.AddComponent<NetworkAnimator>();
339360

361+
var writer = new FastBufferWriter(40, Unity.Collections.Allocator.TempJob);
362+
363+
// Mock a parameter update with an invalid index
364+
MockWritingParameters(ref writer);
365+
366+
var invalidParameters = new ParametersUpdateMessage()
367+
{
368+
Parameters = writer.ToArray()
369+
};
370+
// Expect an error message
371+
LogAssert.Expect(LogType.Error, new System.Text.RegularExpressions.Regex($"parameters. Ignoring the remainger of this {nameof(ParametersUpdateMessage)}!"));
372+
// Pass in the invalid ParametersUpdateMessage
373+
networkAnimator.UpdateParameters(ref invalidParameters);
374+
}
340375

341376
private bool AllTriggersDetected(OwnerShipMode ownerShipMode)
342377
{

0 commit comments

Comments
 (0)