ela-compil / BACnet

BACnet protocol library for .NET :satellite:
https://www.nuget.org/packages/bacnet/
MIT License
215 stars 95 forks source link

IndexOutOfRangeException when calling BacnetClient.ReadPropertyResponse #114

Open joproulx opened 1 year ago

joproulx commented 1 year ago

Issue

When calling ReadPropertyResponse, we get an IndexOutOfRangeException with the following stack trace:

System.IndexOutOfRangeException:
   at System.IO.BACnet.Serialize.EncodeBuffer.Add (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.Serialize.EncodeBuffer.Add (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.Serialize.ASN1.encode_application_object_id (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.Serialize.ASN1.bacapp_encode_application_data (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.Serialize.Services.EncodeReadPropertyAcknowledge (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient+<>c__DisplayClass347_0.<ReadPropertyResponse>b__1 (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient.SendComplexAck (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient+<>c__DisplayClass347_0.<ReadPropertyResponse>b__0 (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient.HandleSegmentationResponse (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)
   at System.IO.BACnet.BacnetClient.ReadPropertyResponse (BACnet, Version=2.0.4.0, Culture=neutral, PublicKeyToken=null)

How to reproduce

Investigation

From what we can see, because the request was coming from a BACnet router, the response need to add a bigger NPDU header and this would increase the max_offset of the buffer to a value higher than the actual size of the buffer as you can see here:

image

So when trying to add response payload (ADPU) bigger than 1476 bytes, the validation with the max_offset goes through even though the size of the buffer is not big enough and we get an IndexOutOfRangeException.

image

Potential fix

Couple of questions for you guys: