Skip to content

Commit 3ba610d

Browse files
arttu-peltonenEvergreen
authored andcommitted
Fix out of bounds read in CoreUnsafeUtils.FixedBufferStringQueue
1 parent c167309 commit 3ba610d

2 files changed

Lines changed: 35 additions & 3 deletions

File tree

Packages/com.unity.render-pipelines.core/Runtime/Common/CoreUnsafeUtils.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,18 @@ public bool TryPush(string v)
6969
}
7070

7171
/// <summary>
72-
/// Pop an element of the queue.
72+
/// Try to pop an element of the queue.
7373
/// </summary>
7474
/// <param name="v">Output result string.</param>
75-
/// <returns>True if an element was succesfuly poped.</returns>
75+
/// <returns>True if an element was successfully popped.</returns>
7676
public bool TryPop(out string v)
7777
{
78+
if (m_ReadCursor + sizeof(int) >= m_BufferEnd)
79+
{
80+
v = null;
81+
return false;
82+
}
83+
7884
var size = *(int*)m_ReadCursor;
7985
if (size != 0)
8086
{
@@ -84,7 +90,7 @@ public bool TryPop(out string v)
8490
return true;
8591
}
8692

87-
v = default;
93+
v = null;
8894
return false;
8995
}
9096

Packages/com.unity.render-pipelines.core/Tests/Editor/FixedBufferStringQueueTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,31 @@ public void PushAndPopOutOfBufferRange()
3636
Assert.False(buffer.TryPush("amet, consectetur adipiscing"));
3737

3838
Assert.AreEqual(1, buffer.Count);
39+
40+
Assert.True(buffer.TryPop(out string v) && v == "Lorem ipsum dolor sit");
41+
Assert.False(buffer.TryPop(out v) && v == null);
42+
}
43+
44+
[Test]
45+
public void PushAndPopOutOfBufferRange_StringSizeNotDivisibleBy4()
46+
{
47+
// UUM-104687: Buffer is created with size of 32 bytes. The test fills the first 30 bytes with a string,
48+
// so 2 bytes are left over in the buffer. After we pop the string out, we check that the next TryPop
49+
// doesn't try to read out of bounds when trying to read the string length.
50+
51+
const int bufferLength = 32;
52+
const int bytesToFill = bufferLength - 2;
53+
const int bytesForString = bytesToFill - sizeof(int);
54+
const int numCharacters = bytesForString / sizeof(char);
55+
56+
string testValue = new string('a', numCharacters);
57+
58+
byte* bufferStart = stackalloc byte[bufferLength];
59+
CoreUnsafeUtils.FixedBufferStringQueue buffer = new CoreUnsafeUtils.FixedBufferStringQueue(bufferStart, bufferLength);
60+
61+
Assume.That(buffer.TryPush(testValue));
62+
Assume.That(buffer.TryPop(out string v));
63+
Assert.False(buffer.TryPop(out v));
3964
}
4065

4166
[Test]
@@ -58,5 +83,6 @@ public void PushAndPopAndClear()
5883
Assert.True(buffer.TryPop(out string v) && v == "elit, sed do eiusmod");
5984
Assert.True(buffer.TryPop(out v) && v == "tempor incididunt ut labore");
6085
}
86+
6187
}
6288
}

0 commit comments

Comments
 (0)