gpt4 book ai didi

c - 为什么这个堆栈粉碎?

转载 作者:太空宇宙 更新时间:2023-11-04 08:55:01 24 4
gpt4 key购买 nike

我得到以下代码(log 函数的一部分):

/* set to 32 on purpose */
#define MAX_LOG_MSG_SZ 32

void log(const char *fmt, ...) {
....

char msg[MAX_LOG_MSG_SZ] = {0};
int nb_bytes = 0;

/* get current time */
time_t now = time(NULL);

char time_buf[32] = {0};

/* format time as `14 Jul 20:00:08`, and exactly 16 bytes */
strftime(time_buf, sizeof(time_buf), "%d %b %H:%M:%S", localtime(&now));

nb_bytes = snprintf(msg, sizeof(msg), "%s", time_buf);

va_list ap;
va_start(ap, fmt);
vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ, fmt, ap);
va_end(ap);

....
}

棘手的事情是当传递长参数(使其超过 32 字节)并将 time_buf 更改为其他小于 32 的值(大于 16,例如 31)时,这些代码将抛出堆栈粉碎。经过几分钟的调试,我将 vsnprintf 调用行更改为

 vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ - nb_bytes, fmt, ap);

stack smashing 消失了,我认为问题已经解决了。

但是:在 time_buf[32](或其他更大的尺寸)上,为什么错误调用

 vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ, fmt, ap);

不是丢一叠砸吗?更确切地说,为什么 msg 的堆栈粉碎与那个不相关 堆栈 (time_buf) 空间有关?

更新:这是我的uname -a 输出:

 Linux coanor 3.5.0-34-generic #55-Ubuntu SMP Thu Jun 6 20:20:19 UTC 2013 i686 i686 i686 GNU/Linux

最佳答案

使用基于堆栈的缓冲区,您必须注意不要溢出分配的缓冲区。正如您自己发现的那样,您使用 vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ, fmt, ap); 引入了可能的缓冲区溢出。这是因为您告诉 vsnprintf,可用空间比实际空间多(因为 nb_bytes = snprintf(msg, sizeof(msg), "%s", time_buf); 已经写入一些字节到缓冲区)。

因此,您的修复方法是传递 MAX_LOG_MSG_SZ - nb_bytes 而不是 MAX_LOG_MSG_SIZE,这对于避免这种影响是正确的。

同样重要的是要知道,无论实际写入到缓冲。

编辑:因此,在您的情况下,您必须在组合过程中跟踪字符串的总长度,以确保您不会超出消息缓冲区的总长度。

关于c - 为什么这个堆栈粉碎?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17639541/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com