Skip to content

Commit

Permalink
Validate data in case allocate too many memory, fix #442 (#448)
Browse files Browse the repository at this point in the history
* Validate data in case allocate too many memory, fix #442

* Check BytesLeft

* bgt => bge
  • Loading branch information
CreateAndInject authored Jan 8, 2022
1 parent 62883b9 commit f4e084f
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 10 deletions.
4 changes: 3 additions & 1 deletion src/DotNet/CustomAttributeReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ CustomAttribute Read(ICustomAttributeType ctor) {
}

List<CANamedArgument> ReadNamedArguments(int numNamedArgs) {
if ((uint)numNamedArgs >= 0x4000_0000 || numNamedArgs * 4 > reader.BytesLeft)
return null;
var namedArgs = new List<CANamedArgument>(numNamedArgs);
for (int i = 0; i < numNamedArgs; i++) {
if (reader.Position == reader.Length)
Expand Down Expand Up @@ -528,7 +530,7 @@ CAArgument ReadArrayArgument(SZArraySig arrayType) {
int arrayCount = reader.ReadInt32();
if (arrayCount == -1) { // -1 if it's null
}
else if (arrayCount < 0)
else if (arrayCount < 0 || arrayCount > reader.BytesLeft)
throw new CABlobParserException("Array is too big");
else {
var array = new List<CAArgument>(arrayCount);
Expand Down
5 changes: 3 additions & 2 deletions src/DotNet/MD/BlobStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ public byte[] Read(uint offset) {
/// <param name="offset">Offset of blob</param>
/// <returns>A new stream</returns>
public DataReader CreateReader(uint offset) {
TryCreateReader(offset, out var reader);
return reader;
if (TryCreateReader(offset, out var reader))
return reader;
return default;
}

/// <summary>
Expand Down
14 changes: 7 additions & 7 deletions src/DotNet/SignatureReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -482,12 +482,12 @@ CallingConventionSig ReadSig() {

T ReadSig<T>(T methodSig) where T : MethodBaseSig {
if (methodSig.Generic) {
if (!reader.TryReadCompressedUInt32(out uint count))
if (!reader.TryReadCompressedUInt32(out uint count) || count > 0x10000)
return null;
methodSig.GenParamCount = count;
}

if (!reader.TryReadCompressedUInt32(out uint numParams))
if (!reader.TryReadCompressedUInt32(out uint numParams) || numParams > 0x10000 || numParams > reader.BytesLeft)
return null;

methodSig.RetType = ReadType();
Expand All @@ -513,7 +513,7 @@ T ReadSig<T>(T methodSig) where T : MethodBaseSig {
/// <param name="callingConvention">First byte of signature</param>
/// <returns>A new <see cref="LocalSig"/> instance</returns>
LocalSig ReadLocalSig(CallingConvention callingConvention) {
if (!reader.TryReadCompressedUInt32(out uint count))
if (!reader.TryReadCompressedUInt32(out uint count) || count > 0x10000 || count > reader.BytesLeft)
return null;
var sig = new LocalSig(callingConvention, count);
var locals = sig.Locals;
Expand All @@ -528,7 +528,7 @@ LocalSig ReadLocalSig(CallingConvention callingConvention) {
/// <param name="callingConvention">First byte of signature</param>
/// <returns>A new <see cref="GenericInstMethodSig"/> instance</returns>
GenericInstMethodSig ReadGenericInstMethod(CallingConvention callingConvention) {
if (!reader.TryReadCompressedUInt32(out uint count))
if (!reader.TryReadCompressedUInt32(out uint count) || count > 0x10000 || count > reader.BytesLeft)
return null;
var sig = new GenericInstMethodSig(callingConvention, count);
var args = sig.GenericArguments;
Expand Down Expand Up @@ -606,7 +606,7 @@ TypeSig ReadType(bool allowTypeSpec = false) {

case ElementType.GenericInst:
nextType = ReadType();
if (!reader.TryReadCompressedUInt32(out num))
if (!reader.TryReadCompressedUInt32(out num) || num > 0x10000 || num > reader.BytesLeft)
break;
var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num);
var args = genericInstSig.GenericArguments;
Expand All @@ -628,7 +628,7 @@ TypeSig ReadType(bool allowTypeSpec = false) {
}
if (!reader.TryReadCompressedUInt32(out num))
break;
if (num > MaxArrayRank)
if (num > rank)
break;
var sizes = new List<uint>((int)num);
for (i = 0; i < num; i++) {
Expand All @@ -638,7 +638,7 @@ TypeSig ReadType(bool allowTypeSpec = false) {
}
if (!reader.TryReadCompressedUInt32(out num))
break;
if (num > MaxArrayRank)
if (num > rank)
break;
var lowerBounds = new List<int>((int)num);
for (i = 0; i < num; i++) {
Expand Down

0 comments on commit f4e084f

Please sign in to comment.