CodeQL documentation

Unvalidated local pointer arithmetic

ID: cs/unvalidated-local-pointer-arithmetic Kind: problem Security severity: 9.3 Severity: warning Precision: high Tags: - security - external/cwe/cwe-119 - external/cwe/cwe-120 - external/cwe/cwe-122 - external/cwe/cwe-788 Query suites: - csharp-code-scanning.qls - csharp-security-extended.qls - csharp-security-and-quality.qls 

Click to see the query in the CodeQL repository

It is dangerous to use the result of a virtual method call in pointer arithmetic without validation if external users can provide their own implementation of the virtual method. For example, if the analyzed project is distributed as a library or framework, then the end-user could provide a new implementation that returns any value.

Recommendation

Always validate the result of virtual methods calls before performing pointer arithmetic to avoid reading or writing outside the bounds of an allocated buffer.

Example

In this example, we write to a given element of an array, using an instance of the PossiblyOverridableClass to determine which element to write to.

In the first case, the GetElementNumber method is called, and the result is used in pointer arithmetic without any validation. If the user can define a subtype of PossiblyOverridableClass, they can create an implementation of GetElementNumber that returns an invalid element number. This would lead to a write occurring outside the bounds of the charArray.

In the second case, the result of GetElementNumber is stored, and confirmed to be within the bounds of the array. Note that it is not sufficient to check that it is smaller than the length. We must also ensure that it’s greater than zero, to prevent writes to locations before the buffer as well as afterwards.

publicclassPossiblyOverridable{publicvirtualintGetElementNumber(){// By default returns 0, which is safereturn0;}}publicclassPointerArithmetic{publicunsafevoidWriteToOffset(PossiblyOverridablepossiblyOverridable,char[]charArray){fixed(char*charPointer=charArray){// BAD: Unvalidated use of virtual method call result in pointer arithmeticchar*newCharPointer=charPointer+possiblyOverridable.GetElementNumber();*newCharPointer='A';// GOOD: Check that the number is viableintnumber=possiblyOverridable.GetElementNumber();if(number>=0&&number<charArray.Length){char*newCharPointer2=charPointer+number;*newCharPointer='A';}}}}

References

close