【发布时间】:2019-08-11 05:40:05
【问题描述】:
我正在对 GCC 的堆栈保护功能进行一些实验以更好地理解它。基本上我指的是this post on stackoverflow。
以下是我的代码。
test.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。
生成文件
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”选项?还是我在这里遗漏了一些其他设置?
【问题讨论】:
-
行为是未定义。由于实际上不需要任何数组写入,因此可以优化数组并且不需要发生堆栈粉碎。
-
优化足够好,可以去掉导致栈崩溃的汇编代码。
-
函数前缀
static,使用Godbolt探索 -
@AnttiHaapala:只是为了理解 - 我在 write_at_index() 中打印数组 [index]。所以需要写数组对吧?
-
您的代码可以替换为
puts("\nwrite_at_index 6 arr[30]=10\n\ntest_stack_overflow 16 Exiting a[0] 0"),没有人会注意到任何区别。