Skip to content

Commit 19c0782

Browse files
tannergoodingt.csala
authored andcommitted
#124513 - Guard Base64Url.DecodeFromChars against non-ASCII input (#124540)
Base64Url.DecodeFromChars in Microsoft.Bcl.Memory has an out-of-bounds read bug: DecodeFrom uses Unsafe.Add with raw char values as indices into a 256-element DecodingMap without checking the DecodeRemaining return value first. Non-ASCII chars (value > ~2048) cause an AccessViolationException on .NET 8. Workaround: Add System.Text.Ascii.IsValid check before decoding to reject non-ASCII input early. Base64/Base64Url only uses ASCII characters, so any non-ASCII input is inherently invalid. Fixes #124513 --------- Co-authored-by: t.csala <t.csala@criteo.com>
2 parents 1f0cdd4 + b5da1db commit 19c0782

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

src/libraries/System.Memory/tests/Base64Url/Base64UrlUnicodeAPIsUnitTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Collections.Generic;
@@ -196,7 +196,8 @@ public static IEnumerable<object[]> EncodeToStringTests_TestData()
196196
}
197197

198198
[Theory]
199-
[InlineData("\u5948cz_T", 0, 0)] // scalar code-path
199+
[InlineData("AB\u1000D", 0, 0)] // scalar code-path, non-ASCII char > 255 (https://github.com/dotnet/runtime/issues/124513)
200+
[InlineData("\u5948cz_T", 0, 0)] // scalar code-path
200201
[InlineData("z_Ta123\u5948", 4, 3)]
201202
[InlineData("\u5948z_T-H7sqEkerqMweH1uSw==", 0, 0)] // Vector128 code-path
202203
[InlineData("z_T-H7sqEkerqMweH1uSw\u5948==", 20, 15)]

src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Base64Helper/Base64DecoderHelper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(TBase64Deco
167167
Debug.Assert(typeof(TBase64Decoder) == typeof(Base64DecoderByte) ? remaining == 4 : remaining < 8);
168168
int i0 = decoder.DecodeRemaining(srcEnd, ref decodingMap, remaining, out uint t2, out uint t3);
169169

170+
if (i0 < 0)
171+
{
172+
goto InvalidDataExit;
173+
}
174+
170175
byte* destMax = destBytes + (uint)destLength;
171176

172177
if (!decoder.IsValidPadding(t3))

0 commit comments

Comments
 (0)