/GS (verificação de segurança de buffer)

Detecta alguns estouros de buffer que substituem o endereço de retorno da função, o endereço do manipulador de exceção ou certos tipos de parâmetros. Causar uma saturação de buffer é uma técnica usada por hackers para explorar o código não impõe restrições de tamanho de buffer.

/GS[-]

Comentários

/GSé ativado por padrão. Se você espera que seu aplicativo para não que nenhuma exposição de segurança, use /GS-. Para obter mais informações sobre /GS, consulte Compilador verifica na profundidade de segurança. Para obter mais informações sobre a supressão de detecção de saturação de buffer, consulte safebuffers.

Verificações de segurança

Nas funções que o compilador reconhece como sujeitos a problemas de saturação de buffer, o compilador aloca espaço na pilha antes do endereço de retorno. Entrada da função, o espaço alocado é carregado com um o cookie de segurança que é calculado de uma vez no carregamento de módulo. Na saída da função e durante o desenrolar do quadro em sistemas operacionais de 64 bits, uma função auxiliar é chamada para certificar-se de que o valor do cookie ainda é o mesmo. Outro valor indica que uma substituição da pilha pode ter ocorrido. Se um valor diferente for detectado, o processo é encerrado.

Buffers de GS

Uma verificação de segurança de saturação de buffer é realizada em um o buffer de GS. Um buffer de GS pode ser um destes procedimentos:

  • Uma matriz maior que 4 bytes, tem mais de dois elementos e tem um tipo de elemento não é um tipo de ponteiro.

  • Uma estrutura de dados, cujo tamanho é de mais de 8 bytes e não ponteiros.

  • Um buffer alocado usando o _alloca função.

  • Qualquer classe ou estrutura que contém um buffer do GS.

Por exemplo, as seguintes instruções declare buffers do 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 seguintes instruções declarar não buffers do GS. As duas primeiras declarações contenham elementos de tipo de ponteiro. As declarações de terceira e quarta declarar matrizes cujo tamanho é muito pequeno. A quinta instrução declara uma estrutura cujo tamanho em uma plataforma x86 não é mais de 8 bytes.

    char *pBuf[20];
    void *pv[20];
    char buf[4];
    int buf[2];
    struct { int a; int b; };

O /GS opção de compilador requer que o cookie de segurança seja inicializada antes de qualquer função que usa o cookie é executar. O cookie de segurança deve ser inicializado na entrada para um arquivo EXE ou DLL. Isso é feito automaticamente se você usar os pontos de entrada padrão do CRT (mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup ou _DllMainCRTStartup). Se você usar um ponto de entrada alternativos, você deve inicializar manualmente o cookie de segurança chamando __security_init_cookie.

O que é protegido.

O /GS opção de compilador protege os seguintes itens:

  • O endereço de retorno de chamada de função.

  • O endereço de um manipulador de exceção para uma função.

  • Parâmetros da função vulnerável.

Em todas as plataformas, /GS tenta detectar saturações de buffer para o endereço de retorno. Saturações de buffer são mais facilmente exploradas em plataformas como, por exemplo, x86 e x64, as convenções de chamada de uso que armazenam o endereço de retorno de uma função chamada na pilha.

Em 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 desenrolar do quadro.

/GSprotege parâmetros vulneráveis que são passados para uma função. Um parâmetro vulnerável é um ponteiro, uma referência de C++, uma C-estrutura (tipo de C++ POD) que contém um ponteiro ou um buffer de GS.

Um parâmetro vulnerável é alocado antes do cookie e variáveis locais. Uma saturação de buffer pode substituir esses parâmetros. E código da função que usa esses parâmetros pode causar um ataque antes que a função retornará e a verificação de segurança é executada. Para minimizar esse risco, o compilador faz uma cópia dos parâmetros vulneráveis durante o prólogo da função e coloca-os abaixo da área de armazenamento para os buffers.

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 do GS.

  • Otimizações (/O opções) não estão ativados.

  • Funções que têm uma lista de argumento variável (...).

  • Funções que são marcadas com nua.

  • Funções que contêm o código de assembly embutido na primeira instrução.

  • Um parâmetro é usado apenas em formas que têm menor probabilidade de ser explorada no caso de uma saturação de buffer.

O que não está protegido

O /GS opção de compilador não protege contra todos os buffer saturação segurança ataques. Por exemplo, se você tiver um buffer e uma vtable em um objeto, uma saturação de buffer pode corromper o vtable.

Mesmo que você use /GS, tente sempre escrever código seguro, que possui nenhum saturações de buffer.

Para definir esta opção de compilador no Visual Studio

  1. Em Solution Explorer, o botão direito do mouse no projeto e, em seguida, clique em Propriedades.

    For more information, see Como: Abrir páginas de propriedades do projeto.

  2. No Property Pages caixa de diálogo, clique no C/C++ pasta.

  3. Clique na A geração de código página de propriedades.

  4. Modificar o Buffer Security Check propriedade.

Para definir esta opção de compilador programaticamente

Exemplo

Este exemplo saturações de um buffer. Isso faz com que o aplicativo falhar em tempo de execução.

// 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);
}

Consulte também

Referência

Opções do compilador

Definindo opções do compilador