ABV.UNICODE.NNTS_MAP

映射函数中非 null 终止的字符串导致的缓冲区溢出

ABV.UNICODE.NNTS_MAP 可检查 MultiByteToWideChar 和 WideCharToMultiByte 映射函数中由非 null 终止的字符串导致的缓冲区溢出状况。通常,当任一函数未自动终止输出字符串时,该检查器便会检测到相应状况。

有关 MultiByteToWideChar 和 WideCharToMultiByte 映射函数运算的详细信息,请参阅 MSDN 网站。

漏洞与风险

如果未正确使用这些映射函数,将导致缓冲区溢出,从而威胁应用程序的安全。为避免在将来发生这种状况,请务必以 null 终止函数的输出字符串。

漏洞代码示例

复制
  #include <windows.h>
  #include <stdio.h>
  #include <wchar.h>
  #include <string.h>
  
  int main() 
  {
      wchar_t wstrTestNNTS[] = L"0123456789ABCDEF";
      char strTestNNTS[16];
      int res = WideCharToMultiByte(CP_UTF8, 0, wstrTestNNTS, -1, strTestNNTS, 16, NULL, NULL);
      printf("res = %d\n", res);
      printf("strTestNNTS = %s\n", strTestNNTS);
      return 0;
  }

Klocwork 为“WideCharToMultiByte”函数生成了一个 NNTS 报告,因为此函数不保证在字符串末尾写入以 null 终止的字符。如果使用目标缓冲区时未检查返回值,非 null 终止的字符串可能溢出。

修正代码示例

复制
  #include <windows.h>
  #include <stdio.h>
  #include <wchar.h>
  #include <string.h>
  
  int main() 
  {
      wchar_t wstrTestNNTS[] = L"0123456789ABCDEF";
      char strTestNNTS[16];
      int res = WideCharToMultiByte(CP_UTF8, 0, wstrTestNNTS, -1, strTestNNTS, 16, NULL, NULL);
      if (res == sizeof(strTestNNTS)) {
          strTestNNTS[res-1] = NULL;
      } else {
          strTestNNTS[res] = NULL;
      }
      printf("res = %d\n", res);
      printf("strTestNNTS = %s\n", strTestNNTS);
      return 0;
  }

在该修正代码示例中,在第 11 到 14 行中检查了函数的返回值,如果需要,可添加以 null 终止的字符。

安全培训

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

扩展

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