A função memcpy() foi indicada para banimento e provavelmente entrará para lista de Banidos SDL da Microsoft no fim deste ano. memcpy() se juntará a outras funções populares como strcpy, strncpy, strcat, strncat que tiveram o mesmo destino por causa de suas vulnerabilidades de segurança através de invasões de buffer.
Muitas foram as atualizações de seguranças lançadas pela Microsoft por causa do memcpy(): MS03-030 (DirectX), MS03-043 (Serviço Messenger), MS03-044 (Ajuda e Suporte), MS05-039 (PnP), MS04-011 (PCT), MS05-030 (Outlook Express), CVE-2007-3999 (MIT Kerberos v5), CVE-2007-4000 (MIT Kerberos v5) dentre outras.
As funções que serão banidas pela Microsoft são: memcpy(), CopyMemory() e RtlCopyMemory(). Para evitar estas funções é preciso adicionar a seguinte linha #pragma ao cabeçalho do arquivo e o compilador avisará sempre que encontrá-las:
#pragma deprecated (memcpy, RtlCopyMemory, CopyMemory)
ou, uma alternativa para C++, usando a seguinte linha:
#define _CRT_SECURE_WARNINGS_MEMORY
ou ainda, para GCC:
#pragma GCC poison memcpy RtlCopyMemory CopyMemory
A função recomendada para substituir memcpy() é memcpy_s(), que tem a seguinte assinatura em VC++ 2008:
errno_t __cdecl memcpy_s( _Out_opt_bytecap_post_bytecount_(_DstSize, _MaxCount) void * _Dst, _In_ rsize_t _DstSize, _In_opt_bytecount_(_MaxCount) const void * _Src, _In_ rsize_t _MaxCount );
memcpy_s() não é à prova de erros; um desenvolvedor pode especificar um destino maior que o tamanho atualmente alocado, levando à mesma vulnerabilidade de segurança que memcpy().
A lista completa do SDL contém muitas funções banidas junto às recomendações das quais devem ser utilizadas para substituí-las:
Descrição | Função banida | Função recomendada |
Cópia de String | strcpy, wcscpy, _tcscpy, _mbscpy, StrCpy, StrCpyA, StrCpyW, lstrcpy, lstrcpyA, lstrcpyW, strcpyA, strcpyW, _tccpy, _mbccpy | strcpy_s |
Concatenação de String | strcat, wcscat, _tcscat, _mbscat, StrCat, StrCatA, StrCatW, lstrcat, lstrcatA, lstrcatW, StrCatBuffW, StrCatBuff, StrCatBuffA, StrCatChainW, strcatA, strcatW, _tccat, _mbccat | strcat_s |
Sprintf | wnsprintf, wnsprintfA, wnsprintfW, sprintfW, sprintfA, wsprintf, wsprintfW, wsprintfA, sprintf, swprintf, _stprintf | sprintf_s |
Tokenizing | strtok, _tcstok, wcstok, _mbstok | strtok_s |
Scanf | scanf, wscanf, _tscanf, sscanf, swscanf, _stscanf | sscanf_s |
Conversões numéricas | _itoa, _itow, _i64toa, _i64tow, _ui64toa, _ui64tot, _ui64tow, _ultoa, _ultot, _ultow | _itoa_s, _itow_s |
Gets | gets, _getts, _gettws | gets_s |
SDL ofereceu um cabeçalho (banned.h) que, ao ser incluído, mostra todos os avisos referentes à funções banidas. Como um método alternativo, o desenvolvedor pode usar a opção do compilador /W4-C4996 na VS2005 ou posterior.