Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Detecta algumas saturações de buffer que substituem o endereço de retorno de uma função, o endereço do manipulador de exceção ou determinados tipos de parâmetros. Causar uma saturação de buffer é uma técnica usada por hackers para explorar o código que não impõe restrições de tamanho de buffer.
Sintaxe
/GS[-]
Comentários
/GS fica ativo por padrão. Se você espera que seu aplicativo não tenha exposição de segurança, use /GS-. Para obter mais informações sobre como suprimir a detecção de saturação de buffer, confira safebuffers.
Verificações de segurança
Nas funções que o compilador reconhece como sujeitas a problemas de saturação de buffer, o compilador aloca espaço na pilha antes do endereço de retorno. Na entrada da função, o espaço alocado é carregado com um cookie de segurança que é calculado uma vez na carga do módulo. Na saída da função e durante o desenrolamento do quadro em sistemas operacionais de 64 bits, uma função auxiliar é chamada para garantir que o valor do cookie ainda seja o mesmo. Um valor diferente indica que uma substituição da pilha possa ter ocorrido. Se um valor diferente for detectado, o processo será encerrado.
Buffers GS
Uma verificação de segurança de saturação de buffer é executada em um buffer GS. Um buffer GS pode ser um destes:
- Uma matriz maior que 4 bytes, com mais de dois elementos e com um tipo de elemento que não é um tipo de ponteiro.
- Uma estrutura de dados cujo tamanho é maior que 8 bytes e que não contém ponteiros.
- Um buffer alocado usando a
_allocafunção. - Qualquer classe ou estrutura que contenha um buffer GS.
Por exemplo, as instruções a seguir declaram buffers GS.
char buffer[20];
int buffer[20];
struct { int a; int b; int c; int d; } myStruct;
struct { int a; char buf[20]; };
No entanto, as instruções a seguir não declaram buffers GS. As duas primeiras declarações contêm elementos do tipo de ponteiro. A terceira e quarta instruções declaram matrizes cujo tamanho é muito pequeno. A quinta instrução declara uma estrutura cujo tamanho em uma plataforma x86 não é superior a 8 bytes.
char *pBuf[20];
void *pv[20];
char buf[4];
int buf[2];
struct { int a; int b; };
Inicializar o cookie de segurança
A opção do compilador /GS exige que o cookie de segurança seja inicializado antes que qualquer função que use o cookie seja executada. O cookie de segurança deve ser inicializado imediatamente na entrada de um EXE ou DLL. Isso será feito automaticamente se você usar os pontos de entrada padrão do VCRuntime: mainCRTStartup, , wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartupou _DllMainCRTStartup. Se você usar um ponto de entrada alternativo, deverá inicializar manualmente o cookie de segurança chamando __security_init_cookie.
O que é protegido
A opção do compilador /GS protege os seguintes itens:
- O endereço de retorno de uma chamada de função.
- O endereço de um manipulador de exceção para uma função.
- Parâmetros de função vulneráveis.
Em todas as plataformas, a /GS tenta detectar saturações de buffer no endereço de retorno. As saturações de buffer são mais facilmente exploradas em plataformas como x86 e x64, que usam convenções de chamada que armazenam o endereço de retorno de uma chamada de função na pilha.
No x86, se uma função usa um manipulador de exceção, o compilador injeta um cookie de segurança para proteger o endereço do manipulador de exceção. O cookie é verificado durante o desenrolamento do quadro.
A /GS protege parâmetros vulneráveis que são passados para uma função. Um parâmetro vulnerável é um ponteiro, uma referência do C++, uma estrutura do C (tipo de POD do C++) que contém um ponteiro ou um buffer GS.
Um parâmetro vulnerável é alocado antes do cookie e das variáveis locais. Um saturação de buffer pode substituir esses parâmetros. E o código na função que usa esses parâmetros pode causar um ataque antes que a função retorne e a verificação de segurança seja executada. Para minimizar esse perigo, o compilador faz uma cópia dos parâmetros vulneráveis durante o prólogo da função e a coloca abaixo da área de armazenamento de qualquer buffer.
O compilador não faz cópias de parâmetros vulneráveis nas seguintes situações:
- Funções que não contêm um buffer GS.
- As otimizações (
/Oopções) não estão habilitadas. - Funções que têm uma lista de argumentos variáveis (...).
- Funções marcadas com naked.
- Funções que contêm código de assembly embutido na primeira instrução.
- Um parâmetro é usado apenas de maneiras menos propensas a exploração no caso de uma saturação de buffer.
O que não é protegido
A opção do compilador /GS não protege contra todos os ataques de segurança de saturação de buffer. Por exemplo, se você tiver um buffer e uma vtable em um objeto, uma saturação de buffer poderá corromper a vtable.
Mesmo que você use a /GS, sempre tente escrever um código seguro que não tenha nenhuma saturação de buffer.
Para definir essa opção do compilador no Visual Studio
- Abra a caixa de diálogo Páginas de Propriedades do projeto. Para obter detalhes, confira Definir as propriedades de build e do compilador do C++ no Visual Studio.
- Selecione a página de propriedades Propriedades da Configuração>C/C++>Geração de Código.
- Modifique a propriedade Verificação de Segurança do Buffer.
Para definir essa opção do compilador via programação
- Consulte BufferSecurityCheck.
Exemplo
Este exemplo satura um buffer. Isso faz com que o aplicativo falhe no runtime.
// compile with: /c /W1
#include <cstring>
#include <stdlib.h>
#pragma warning(disable : 4996) // for strcpy use
// Vulnerable function
void vulnerable(const char *str) {
char buffer[10];
strcpy(buffer, str); // overrun buffer !!!
// use a secure CRT function to help prevent buffer overruns
// truncate string to fit a 10 byte buffer
// strncpy_s(buffer, _countof(buffer), str, _TRUNCATE);
}
int main() {
// declare buffer that is bigger than expected
char large_buffer[] = "This string is longer than 10 characters!!";
vulnerable(large_buffer);
}
Confira também
Opções do compilador MSVC
Sintaxe da linha de comando do compilador MSVC