Erro: dynamic-stack-buffer-overflow
Erro na limpeza de endereço: dynamic-stack-buffer-overflow
Este exemplo mostra o erro resultante de um acesso de buffer fora dos limites de um objeto alocado em pilha.
Exemplo – alloca
estouro (à direita)
// example1.cpp
// dynamic-stack-buffer-overflow error
#include <malloc.h>
__declspec(noinline)
void foo(int index, int len) {
volatile char *str = (volatile char *)_alloca(len);
// reinterpret_cast<long>(str) & 31L;
str[index] = '1'; // Boom !
}
int main(int argc, char **argv) {
foo(33, 10);
return 0;
}
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
Exemplo – alloca
overflow (à direita)
// example2.cpp
// dynamic-stack-buffer-overflow error
#include <malloc.h>
__declspec(noinline)
void foo(int index, int len) {
volatile char *str = (volatile char *)_alloca(len);
str[index] = '1'; // Boom!
}
int main(int argc, char **argv) {
foo(-1, 10);
return 0;
}
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
Erro resultante – alloca
overflow (à esquerda)
Exemplo – várias chamadas para alloca
// example3.cpp
// dynamic-stack-buffer-overflow error
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define SIZE 7
extern void nothing();
int x=13,*aa,*bb,y=0;
int fail = 0;
int tmp;
int main()
{
int* cc;
int i;
int k = 17;
__try {
tmp = k;
aa = (int*)_alloca(SIZE * sizeof(int));
if (((int)aa) & 0x3)
fail = 1;
for (i = 0; i < SIZE; i++) {
aa[i] = x + 1 + i;
}
bb = (int*)_alloca(x * sizeof(int));
if (((int)bb) & 0x3)
fail = 1;
for (i = 0; i < x; i++) {
bb[i] = 7;
bb[i] = bb[i] + i;
}
{
int s = 112728283;
int ar[8];
for (i = 0; i < 8; i++)
ar[i] = s * 17 * i;
}
cc = (int*)_alloca(x);
if (((int)cc) & 0x3)
fail = 1;
cc[0] = 0;
cc[1] = 1;
cc[2] = 2;
cc[3] = 3; // <--- Boom!
for (i = 0; i < x; i++)
if (bb[i] != (7 + i))
fail = 1;
if (tmp != k)
fail = 1;
if (fail) {
printf("fail\n");
exit(7);
}
printf("%d\n", (*cc) / y);
printf("fail\n");
exit(7);
}
__except (1)
{
for (i = 0; i < SIZE; i++)
if (aa[i] != (x + i + 1))
fail = 1;
if (fail) {
printf("fail\n");
exit(7);
}
printf("pass\n");
exit(0);
}
}
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 – várias chamadas para a alloca
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
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de