NPD.FUNC.CALL.MIGHT

可能存在的空指针可能通过条件函数调用被取消引用

尝试使用空指针访问数据将导致运行时错误。当程序取消引用某个预期为有效但结果为空值的指针,就会发生空指针取消引用。发生空指针取消引用缺陷通常是由于错误处理或争用情况无效,而且往往会导致程序异常中止。在 C/C++ 代码中对指针取消引用之前,必须对其进行检查以确认它不为空值。

NPD 检查器会查找那些对空指针或可能为空的指针进行取消引用的实例。

NPD.FUNC.CALL.MIGHT 检查器标记了那些来自可能返回空值的函数调用的指针值之后可能被传递给某个不进行空值检查就可能对其取消引用的函数的情况。

漏洞与风险

空指针取消引用通常会导致进程失败。这些问题通常是因为无效的异常处理而发生的。

缓解与预防

要避免该漏洞:

  • 对所有将返回值的函数进行空值检查
  • 确保所有外部输入都经过验证
  • 明确初始化变量
  • 确保对不同寻常的异常进行正确处理

漏洞代码示例

复制
  void reassign(int *argument, int *p) {
    if (goodEnough(argument)) return;
    *argument = *p;
  }
  
  int *mymalloc() {
    int *res = malloc(sizeof(int));
    if (!res) return 0;
    *res = 0;
   return res;
 }
 
 void npd_func_call_might(int *argument) {
   int *p = mymalloc();
   if (someCondition()){
     p = f();
   }
   reassign(argument, p);
 }

根据第 8 行的条件语句的结果,可能将空指针传递给函数 npd_func_call_might,根据第 15 行的条件,在此可能对其取消引用。该类型漏洞会产生无法预料的意外结果。

修正代码示例

复制
  void reassign(int *argument, int *p) {
    if (goodEnough(argument)) return;
    *argument = *p;
  }
  
  int *mymalloc() {
    int *res = malloc(sizeof(int));
    if (!res) return 0;
    *res = 0;
   return res;
 }
 
 void npd_func_call_might(int *argument) {
   int *p = mymalloc();
   if (someCondition()){
     p = f();
   }
   if (p!= 0) reassign(argument, p);
 }

在经修正的代码中,*p 在第 18 行进行了空值检查,随后被取消引用。

安全培训

应用程序安全培训材料由 Secure Code Warrior 提供。

扩展

此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 C/C++ 分析。