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

标签 c gcc stack

我正在对 GCC 的堆栈保护功能进行一些实验,以更好地理解它。基本上我提到了this post on stackoverflow .

以下是我的代码。

测试.c

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

以下是我的 makefile。

Makefile

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

我使用的是gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

当我构建并运行 test.out 时,我按预期得到“检测到堆栈粉碎”崩溃。

但是,如果我将优化级别更改为 O3,(CFLAGS=-O3 -fstack-protector -fstack-protector-all) 并构建并执行 test.out,我不会观察到崩溃.

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

最佳答案

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

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

关于c - GCC 具有优化级别的堆栈保护功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55262274/

相关文章:

c - 为什么 func() 和 func(void) 不同

c - 如何使用 llvm-link 链接库

c++ - 为什么 g++ 在 LIBRARY_PATH/../lib64 中查找,这在哪里记录?

c - 检查字符串是否回文时出错

java - 使用堆栈获取逻辑子表达式

计算二维数组中的页面错误数

c++ - 是否有 C/C++ API 用于读取 WIndows 上的 CPU 性能监控计数器 (PMC)(适用于 intel 和 AMD 处理器)?

c++ - 是否有针对 "conditional expression is constant"的 gcc 警告?

c++ - 使用 GDB 在 main() 之前调试错误

assembly - 有什么可以防止汇编中的堆栈溢出吗?