GCC的堆栈保护功能具有优化级别

时间:2019-03-20 13:47:11

标签: c gcc stack

我正在使用GCC的堆栈保护功能进行一些实验,以更好地理解它。基本上,我指的是this post on stackoverflow

以下是我的代码。

test.c

bool DirectoryExists( const char* absolutePath ){
    if( _access( absolutePath, 0 ) == 0 ){
        struct stat status;
        stat( absolutePath, &status );
        return (status.st_mode & S_IFDIR) != 0;
    }
    return false;
}

marca = "database\\"+marca;
CreateDirectory (marca.c_str(), NULL);
// useless operation
if(! DirectoryExists(marca.c_str() )  )
{
    cout<<" Error !";
    return -1;
}

以下是我的makefile。

制作文件

#include <stdio.h>

void write_at_index(char *arr, unsigned int idx, char val)
{
    arr[idx] = val;
    printf("\n%s %d arr[%u]=%d\n", __func__, __LINE__,
        idx, arr[idx]);
}

void test_stack_overflow()
{
    char a[16] = {0}; //Array of 16 bytes.

    write_at_index(a, 30/*idx*/, 10/*val*/); //Ask the other function to access 30th index.

    printf("\n%s %d Exiting a[0] %d\n", __func__, __LINE__, a[0]);
}

int main()
{
    test_stack_overflow();
    return 0;
}

我正在使用gcc(Ubuntu 7.3.0-27ubuntu1〜18.04)7.3.0

构建并运行test.out时,按预期方式出现“检测到堆栈崩溃”崩溃。

但是,如果我将优化级别更改为O3 CC=gcc BIN=./test.out SRCS=./test.c all: $(BIN) OBJ = ${SRCS:.c=.o} CFLAGS=-O0 -fstack-protector -fstack-protector-all $(OBJ): %.o: %.c $(CC) $(CFLAGS) $(INCLUDES) -c $*.c -o $*.o $(BIN): $(OBJ) $(CC) -o $@ $< rm -rf ./*.o clean: rm -rf ./*.out rm -rf ./*.o 并生成并执行test.out,则不会观察到崩溃。

所以我的问题是,启用优化后,编译器是否会删除“ -fstack-protector”选项?还是我在这里缺少其他设置?

1 个答案:

答案 0 :(得分:1)

在更高的优化级别上,将write_at_index内联到test_stack_overflow中,GCC会检测到整个数组a没有以任何有意义的方式被使用,并消除了它。结果,存储到阵列中以及相关的缓冲区溢出都消失了。您必须添加一个编译器屏障以防止这种情况发生。

此外,单字节溢出仅在设法击中金丝雀(或返回地址)时才触发堆栈保护器崩溃。因此,它们不是练习堆栈溢出检测代码的好方法。