ABV.UNICODE.BOUND_MAP

缓冲区溢出 — 映射函数中超出边界的数组索引

ABV.UNICODE.BOUND_MAP 可检查 MultiByteToWideChar 和 WideCharToMultiByte 映射函数中引起的缓冲区溢出状况。通常,当 WideCharToMultiByte 错误地检查缓冲区边界并且缓冲区溢出时,该检查器便会检测到相应状况。

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

漏洞与风险

如果未正确使用这些映射函数,将导致缓冲区溢出,从而威胁应用程序的安全。使用 MultiByteToWideChar 尤其容易导致缓冲区溢出,因为输入缓冲区的大小是以字符串表示的字节数,输出缓冲区的大小则是字符数。(WideCharToMultiByte 函数的情况则正好相反。)为避免在将来发生这种状况,请务必为缓冲区接收的数据类型指定适合的缓冲区大小。

漏洞代码示例

复制
  #include "stdafx.h"
  #include <string.h>
  #include <iostream>
  
  using namespace std;
  
  void convert(WCHAR *wcsPath)
  {
      char cpszPath[5] ="";
      WideCharToMultiByte(CP_ACP, 0, wcsPath, -1, cpszPath, 260, 0, 0);
      cout << cpszPath << endl;
  }

                                                

Klocwork 针对第 10 行生成缓冲区溢出报告,指出 WideCharToMultiByte 函数可能错误地检查缓冲区边界并且使大小为 260 的缓冲区 cpszPath 溢出。在本例中,由于未验证输入缓冲区大小,WideCharToMultiByte 函数导致了缓冲区溢出。

修正代码示例

复制
  #include "stdafx.h"
  #include <string.h>
  #include <iostream>
  
  using namespace std;
  
  
  void convert(WCHAR sText[100]) {
      char szTemp[20];
      int nSize = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, sText, -1, szTemp, 0, 0, 0);
      if (nSize > sizeof(szTemp)) 
      {
          return;
      }else
      { 
          WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, sText, -1, szTemp, nSize , 0, 0); 
      }
      cout << szTemp << endl;
  }

                                                

如果在该修正代码示例中,目标缓冲区的大小为 0,则该函数将返回进行转换所需的字节数。进行转换前,需将输入字符大小与缓冲区大小进行比较。

安全培训

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

扩展

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