CodeQL 文档

未经验证的本地指针运算

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

点击查看 CodeQL 存储库中的查询

如果外部用户可以提供自己的虚方法实现,则在指针运算中使用虚方法调用的结果而不进行验证是危险的。例如,如果分析的项目作为库或框架分发,则最终用户可以提供一个返回任何值的新实现。

建议

在执行指针运算之前始终验证虚方法调用的结果,以避免在分配的缓冲区边界之外进行读写。

示例

在此示例中,我们使用 PossiblyOverridableClass 的实例写入数组的给定元素,以确定要写入哪个元素。

在第一种情况下,调用 GetElementNumber 方法,并且在指针运算中使用结果而不进行任何验证。如果用户可以定义 PossiblyOverridableClass 的子类型,则他们可以创建返回无效元素编号的 GetElementNumber 实现。这将导致在 charArray 的边界之外发生写入。

在第二种情况下,存储 GetElementNumber 的结果,并确认它在数组的边界内。请注意,仅检查它是否小于长度是不够的。我们还必须确保它大于零,以防止写入缓冲区之前和之后的位置。

public class PossiblyOverridable
{
    public virtual int GetElementNumber()
    {
        // By default returns 0, which is safe
        return 0;
    }
}

public class PointerArithmetic
{
    public unsafe void WriteToOffset(PossiblyOverridable possiblyOverridable,
                                     char[] charArray)
    {
        fixed (char* charPointer = charArray)
        {
            // BAD: Unvalidated use of virtual method call result in pointer arithmetic
            char* newCharPointer = charPointer + possiblyOverridable.GetElementNumber();
            *newCharPointer = 'A';
            // GOOD: Check that the number is viable
            int number = possiblyOverridable.GetElementNumber();
            if (number >= 0 && number < charArray.Length)
            {
                char* newCharPointer2 = charPointer + number;
                *newCharPointer = 'A';
            }
        }
    }
}

参考

  • ©GitHub 公司
  • 条款
  • 隐私