다음을 통해 공유


오류: dynamic-stack-buffer-overflow

삭제자 오류 해결: dynamic-stack-buffer-overflow

이 예제에서는 스택 할당 개체의 범위를 벗어난 버퍼 액세스에서 발생하는 오류를 보여 줍니다.

예 - alloca 오버플로(오른쪽)

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

이 예제를 빌드하고 테스트하려면 Visual Studio 2019 버전 16.9 이상 개발자 명령 프롬프트에서 다음 명령을 실행합니다.

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

결과 오류

예제 1에서 동적 스택 버퍼 오버플로 오류를 표시하는 디버거의 스크린샷

예 - alloca 오버플로(왼쪽)

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

이 예제를 빌드하고 테스트하려면 Visual Studio 2019 버전 16.9 이상 개발자 명령 프롬프트에서 다음 명령을 실행합니다.

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

결과 오류 - alloca 오버플로(왼쪽)

예제 2에서 동적 스택 버퍼 오버플로 오류를 표시하는 디버거의 스크린샷

예제 - 여러 호출 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);
    }
}

이 예제를 빌드하고 테스트하려면 Visual Studio 2019 버전 16.9 이상 개발자 명령 프롬프트에서 다음 명령을 실행합니다.

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

결과 오류 - alloca에 대한 여러 호출

예제 3에서 동적 스택 버퍼 오버플로 오류를 표시하는 디버거의 스크린샷

참고 항목

AddressSanitizer 개요
AddressSanitizer 알려진 문제
AddressSanitizer 빌드 및 언어 참조
AddressSanitizer 런타임 참조
AddressSanitizer 섀도 바이트
AddressSanitizer 클라우드 또는 분산 테스트
AddressSanitizer 디버거 통합
AddressSanitizer 오류 예제