/GS (Sprawdzanie zabezpieczeń bufora)

Wykrywanie niektórych przekroczeń buforu, które zastępują adres zwrotny funkcji, adres obsługi wyjątków lub niektóre typy parametrów.Powodowanie przepełnienia buforu jest techniką używaną przez hakerów do wykorzystywania kodu, który nie wymusza ograniczeń rozmiaru buforu.

/GS[-]

Uwagi

Domyślnie /GS jest włączona.Jeśli aplikacja nie ma zagrożeń bezpieczeństwa, należy użyć /GS-.Aby uzyskać więcej informacji dotyczących /GS, zobacz Sprawdzanie zabezpieczeń kompilatora w głębi.Aby uzyskać więcej informacji dotyczących pomijania wykrywań przepełnień buforu, zobacz safebuffers.

Sprawdzanie zabezpieczeń.

W funkcjach, które kompilator uznaje problem przekroczenia buforu, kompilator przydziela miejsce na stosie przed adresem zwrotnym.Przy wejściu do funkcji, przydzielony obszar jest ładowany z plik cookie zabezpieczeń, który jest obliczany raz przy ładowaniu modułu.Po wyjściu z funkcji, a podczas odwracania ramki na 64-bitowych systemach operacyjnych wywoływana jest funkcja pomocnika, aby upewnić się, że wartość pliku cookie jest wciąż taka sama.Inna wartość wskazuje, że mogło wystąpić przepełnienie stosu.Jeśli zostanie wykryta inna wartość, proces jest zakończony.

Bufory GS

Sprawdzanie zabezpieczeń przepełnienia buforu jest wykonywane w buforze GS.Buforem GS może być:

  • Tablica, która jest większa niż 4 bajty, ma więcej niż dwa elementy i ma typ elementu, który nie jest typem wskaźnika.

  • Struktura danych, której rozmiar jest większy niż 8 bajtów i nie zawiera żadnych wskaźników.

  • Przydzielanie buforu przy użyciu funkcji _alloca.

  • Dowolna klasa lub struktura, która zawiera bufor GS.

Na przykład, poniższe instrukcje deklarują bufory GS.

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

Jednakże, poniższe instrukcje nie deklarują buforów GS.Pierwsze dwie deklaracje zawierają elementy typu wskaźnika.Trzecia i czwarta instrukcja deklaruje tablicę, której rozmiar jest za mały.Piąta instrukcja deklaruje strukturę, której rozmiar na platformie x86 jest mniejszy niż 8 bajtów.

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

Opcja kompilatora /GS wymaga zainicjowania pliku cookie zabezpieczeń przed uruchomieniem wszelkich funkcji, które korzystają z pliku cookie podczas uruchamiania.Plik cookie zabezpieczeń musi być zainicjowany na wejściu do EXE lub DLL.Odbywa się to automatycznie jeśli używasz domyślnych punktów wejścia CRT (mainCRTStartup, wmainCRTStartup, WinMainCRTStartup, wWinMainCRTStartup, lub _DllMainCRTStartup).Jeśli używasz alternatywnego punktu wejścia, należy ręcznie zainicjować plik cookie zabezpieczeń, wywołując __security_init_cookie.

Co jest chronione

Opcja kompilatora /GS chroni następujące elementy:

  • Adres zwrotny w wywołaniu funkcji.

  • Adres obsługi wyjątków dla funkcji.

  • Zagrożone parametry funkcji.

Na wszystkich platformach /GS próbuje wykryć przepełnienia buforu w adresie zwrotnym.Przekroczenia buforu są łatwiej wykorzystywane na platformach takich jak x86 i x64, które używają konwencji, która przechowuje adres zwrotny wywołania funkcji na stosie.

Na platformach x86, jeśli funkcja wykorzystuje obsługę wyjątków, kompilator wstrzykuje plik cookie zabezpieczeń, aby chronić adres obsługi wyjątków.Plik cookie jest sprawdzany w trakcie odwracania ramki.

/GS chroni zagrożone parametry przekazywane do funkcji.Zagrożony parametr jest wskaźnikiem, odwołaniem języka C++, C-structure (typ C++ POD), który zawiera wskaźnik lub bufor GS.

Parametr zagrożony jest przydzielany przed cookie i zmiennymi lokalnymi.Przepełnienie buforu można zastąpić te parametry.Kod funkcji, która korzysta z tych parametrów może spowodować atak, zanim funkcja zwróci i wykona sprawdzanie zabezpieczeń.Aby zminimalizować niebezpieczeństwo, kompilator tworzy kopię parametrów zagrożonych podczas prologu funkcji i umieszcza je pod obszarem magazynowania dla wszelkich buforów.

Kompilator nie tworzy kopii zagrożonych parametrów w następujących sytuacjach:

  • Funkcje, które nie zawierają buforu GS.

  • Optymalizacje (/O opcje) nie są włączone.

  • Funkcje, które mają listę argumentów zmiennych (...).

  • Funkcje, które są oznaczone jako naked.

  • Funkcje, które zawierają wbudowany zestaw kodu w pierwszej instrukcji.

  • Parametr jest używany tylko w sposób, który ogranicza możliwość wykorzystania tej luki w przypadku przepełnienia buforu.

Co nie jest chronione

Opcja kompilatora /GS nie chroni przed wszystkimi atakami przepełnień buforu.Na przykład, jeśli masz bufor i vtable w obiekcie, przepełnienie buforu może spowodować uszkodzenie vtable.

Nawet jeśli używasz /GS, zawsze staraj się pisać bezpieczny kod, który nie przepełnia buforu.

Aby ustawić opcję kompilatora w programie Visual Studio

  1. W Eksploratorze rozwiązania, kliknij prawym przyciskiem myszy projekt, a następnie kliknij Właściwości.

    Aby uzyskać dodatkowe informacje, zobacz Porady: otwieranie stron właściwości projektów.

  2. W oknie dialogowym Strony właściwości, kliknij folder C/C++.

  3. Kliknij stronę właściwości Generowanie kodu.

  4. Zmodyfikuj właściwość Sprawdzanie zabezpieczeń buforu.

Aby programowo ustawić tę opcję kompilatora

Przykład

W tym przykładzie zostanie przepełniony bufor.Powoduje to awarię aplikacji w środowisku uruchomieniowym.

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

Zobacz też

Informacje

Opcje kompilatora

Ustawianie opcji kompilatora