Compartilhar via


Erro: stack-buffer-overflow

Erro na limpeza de endereço: estouro de buffer de pilha

Um estouro de buffer de pilha pode acontecer de várias maneiras em C ou C++. Fornecemos vários exemplos para essa categoria de erro que você pode capturar por um recompilamento simples.

Erro: estouro de buffer de pilha

// example1.cpp
// stack-buffer-overflow error
#include <string.h>

int main(int argc, char **argv) {
    char x[10];
    memset(x, 0, 10);
    int res = x[argc * 10];  // Boom! Classic stack buffer overflow

    return res;
}

Para compilar e testar esse exemplo, execute estes comandos em um prompt de comando do desenvolvedor do Visual Studio 2019 versão 16.9 ou posterior:

cl example1.cpp /fsanitize=address /Zi
devenv /debugexe example1.exe

Erro resultante

Captura de tela do depurador exibindo erro de estouro de buffer de pilha no exemplo 1.

Exemplo: matemática do buffer de pilha

// example2.cpp
// stack-buffer-overflow error
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main(int argc, char **argv) {
    assert(argc >= 2);
    int idx = atoi(argv[1]);
    char AAA[10], BBB[10], CCC[10];
    memset(AAA, 0, sizeof(AAA));
    memset(BBB, 0, sizeof(BBB));
    memset(CCC, 0, sizeof(CCC));
    int res = 0;
    char *p = AAA + idx;
    printf("AAA: %p\ny: %p\nz: %p\np: %p\n", AAA, BBB, CCC, p);

    return *(short*)(p) + BBB[argc % 2] + CCC[argc % 2];  // Boom! ... when argument is 9
}

Para compilar e testar esse exemplo, execute estes comandos em um prompt de comando do desenvolvedor do Visual Studio 2019 versão 16.9 ou posterior:

cl example2.cpp /fsanitize=address /Zi
devenv /debugexe example2.exe 9

Erro resultante: matemática do buffer de pilha

Captura de tela do depurador exibindo erro de estouro de buffer de pilha no exemplo 2.

Exemplo: conversão de redução incorreta na pilha

// example3.cpp
// stack-buffer-overflow error
class Parent {
public:
    int field;
};

class Child : public Parent {
public:
    volatile int extra_field;
};

int main(void) {

    Parent p;
    Child *c = (Child*)&p;
    c->extra_field = 42;  // Boom !

    return (c->extra_field == 42);
}

Para compilar e testar esse exemplo, execute estes comandos em um prompt de comando do desenvolvedor do Visual Studio 2019 versão 16.9 ou posterior:

cl example3.cpp /fsanitize=address /Zi
devenv /debugexe example3.exe

Erro resultante: conversão de redução incorreta na pilha

Captura de tela do depurador exibindo erro de estouro de buffer de pilha no exemplo 3.

Confira também

Visão geral do AddressSanitizer
Problemas conhecidos do AddressSanitizer
Referência de linguagem e build do AddressSanitizer
Referência de runtime do AddressSanitizer
Bytes de sombra de AddressSanitizer
Nuvem do AddressSanitizer ou teste distribuído
Integração do depurador do AddressSanitizer
Exemplos de erro do AddressSanitizer