/GS (kontrola zabezpečení vyrovnávací paměti)

Rozpozná některá přetečení vyrovnávací paměti, která přepisují návratovou adresu funkce, adresu obslužné rutiny výjimky nebo určité typy parametrů. Přetečení vyrovnávací paměti je technika používána hackery ke zneužití kódu, která nevynucuje omezení velikosti vyrovnávací paměti.

Syntaxe

/GS[-]

Poznámky

/GS je ve výchozím nastavení zapnutý. Pokud očekáváte, že vaše aplikace nebude mít žádnou bezpečnostní expozici, použijte /GS-. Další informace o potlačení detekce přetečení vyrovnávací paměti najdete v tématu safebuffers.

Kontroly zabezpečení

Pro funkce, u kterých kompilátor rozpozná možnost problémů přetečení vyrovnávací paměti, přidělí místo v zásobníku před návratovou adresou. Při zadávání funkce se přidělený prostor načte souborem cookie zabezpečení, který se vypočítá jednou při načtení modulu. Při ukončení funkce a během rozbalování rámce v 64bitových operačních systémech je zavolána pomocná funkce, která zjišťuje, zda se hodnota souboru cookie nezměnila. Jiná hodnota naznačuje, že mohlo dojít k přepsání zásobníku. Je-li zjištěna jiná hodnota, proces se ukončí.

Vyrovnávací paměti GS

V vyrovnávací paměti GS se provádí kontrola přetečení vyrovnávací paměti. Vyrovnávací paměť GS může být jedna z následujících:

  • Pole, které je větší než čtyři bajty, má více než dva prvky a má typ prvků, který není typem ukazatele.

  • Datová struktura, jejíž velikost je více než 8 bajtů a která neobsahuje žádné ukazatele.

  • Vyrovnávací paměť přidělená pomocí funkce _alloca .

  • Libovolná třída nebo struktura obsahující vyrovnávací paměť GS.

Následující příkazy jsou příkladem deklarace vyrovnávacích pamětí GS.

char buffer[20];
int buffer[20];
struct { int a; int b; int c; int d; } myStruct;
struct { int a; char buf[20]; };

Následující příkazy však vyrovnávací paměti GS nedeklarují. První dvě deklarace obsahují prvky typu ukazatele. Třetí a čtvrtý příkaz deklarují příliš malé pole. Pátý příkaz deklaruje strukturu, jejíž velikost na platformě x86 není více než 8 bajtů.

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

Možnost kompilátoru /GS vyžaduje inicializaci souboru cookie zabezpečení před spuštěním jakékoli funkce, která používá soubor cookie. Soubor cookie zabezpečení musí být inicializován okamžitě při vstupu do exe nebo knihovny DLL. To se provádí automaticky, pokud použijete výchozí vstupní body VCRuntime: mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup nebo _DllMainCRTStartup. Pokud používáte alternativní vstupní bod, musíte ručně inicializovat soubor cookie zabezpečení voláním __security_init_cookie.

Chráněné položky

Možnost kompilátoru /GS chrání následující položky:

  • Návratová adresa volání funkce.

  • Adresa obslužné rutiny výjimky pro funkci.

  • Ohrožené parametry funkce.

Na všech platformách se /GS pokusí rozpoznat přetečení vyrovnávací paměti na zpáteční adresu. Přetečení vyrovnávací paměti lze snadněji zneužít na platformách jako x86 a x64, které využívají konvence volání ukládající návratovou adresu volání funkce do zásobníku.

Pokud na platformě x86 funkce používá obslužnou rutinu výjimky, kompilátor pro ochranu adresy rutiny zavede soubor cookie zabezpečení. Soubor cookie je kontrolován během odvíjení rámce.

/GS chrání ohrožené parametry , které se předávají do funkce. Ohroženým parametrem je ukazatel, odkaz C++, struktura jazyka C (typ C++ POD) obsahující ukazatel či vyrovnávací paměť GS.

Ohrožený parametr je přidělen před souborem cookie nebo lokálními proměnnými. Přetečení vyrovnávací paměti může tyto parametry přepsat. Kód ve funkci, která tyto parametry používá, by mohl způsobit útok dříve, než funkce vrátí hodnotu a je provedena bezpečnostní kontrola. Aby bylo nebezpečí minimalizováno, kompilátor během prologu funkce vytváří kopii ohrožených parametrů a vkládá je pod oblast úložiště pro jakoukoli vyrovnávací paměť.

Kompilátor nevytváří kopie ohrožených parametrů v následujících situacích:

  • Funkce, které neobsahují vyrovnávací paměť GS.

  • Optimalizace (/O možnosti) nejsou povolené.

  • Funkce se proměnným seznamem argumentů (...).

  • Funkce, které jsou označené nahým.

  • Funkce obsahující jako první příkaz vložený kód sestavení.

  • Parametr je používán pouze způsobem, jehož zneužití je v případě přetečení vyrovnávací paměti méně pravděpodobné.

Nechráněné položky

Možnost kompilátoru /GS nechrání před všemi útoky zabezpečení přetečením vyrovnávací paměti. Obsahuje-li například objekt vyrovnávací paměť a tabulku vtable, přetečení vyrovnávací paměti by mohlo tabulku vtable poškodit.

I když používáte /GS, vždy se pokuste napsat zabezpečený kód, který nemá přetečení vyrovnávací paměti.

Nastavení této možnosti kompilátoru v sadě Visual Studio

  1. Otevřete dialogové okno Stránky vlastností projektu. Podrobnosti najdete v tématu Nastavení kompilátoru C++ a vlastností sestavení v sadě Visual Studio.

  2. Vyberte stránku vlastností vlastnosti konfigurace>C/C++>Generování kódu.

  3. Upravte vlastnost Kontrola zabezpečení vyrovnávací paměti.

Programové nastavení tohoto parametru kompilátoru

Příklad

V této ukázce dojde k přetečení vyrovnávací paměti. Z tohoto důvodu dojde za běhu aplikace k chybě.

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

Viz také

Parametry kompilátoru MSVC
Syntaxe příkazového řádku kompilátoru MSVC