gpt4 book ai didi

security - 堆栈溢出是安全漏洞吗?

转载 作者:行者123 更新时间:2023-12-04 11:15:50 24 4
gpt4 key购买 nike

注意:这个问题与堆栈溢出有关(想想无限递归),而不是缓冲区溢出。

如果我编写了一个正确的程序,但它接受来自 Internet 的输入,该输入决定了它调用的递归函数中的递归级别,这是否足以让某人破坏机器?

我知道有人可能会通过导致堆栈溢出来使进程崩溃,但是他们可以注入(inject)代码吗?或者 c 运行时是否检测到堆栈溢出情况并干净地中止?

只是好奇...

最佳答案

快速复习

首先,您需要了解现代操作系统中的基本保护单元是进程和内存页面。进程是内存保护域;它们是操作系统执行安全策略的级别,因此它们与正在运行的程序密切相关。 (如果他们不这样做,要么是因为程序在多个进程中运行,要么是因为程序在某种框架中共享;后一种情况有可能是“安全有趣的”,但那是“另一回事了。)虚拟内存页面是硬件应用安全规则的级别;进程内存中的每个页面都有一些属性,这些属性决定了进程可以使用该页面做什么:它是否可以读取该页面,是否可以写入该页面以及是否可以在其上执行程序代码(尽管第三个属性更多很少使用而不是应该使用)。编译后的程序代码被映射到内存中,页面既可读又可执行,但不可写,而堆栈应该可读可写,但不可执行。大多数内存页根本不可读、不可写或可执行;操作系统只允许进程使用它明确要求的尽可能多的页面,这就是内存分配库(malloc() 等)为您管理的内容。

分析

假设每个堆栈帧小于内存页[1],因此,当程序在堆栈中前进时,它会写入每个页面,操作系统(即运行时的特权部分)至少在原则上可以检测堆栈溢出如果发生这种情况,可靠地终止程序。基本上,进行这种检测的所有事情都是在堆栈末尾有一个程序无法写入的页面;如果程序试图写入它,内存管理硬件会捕获它并且操作系统有机会进行干预。

如果操作系统可能被欺骗而不设置这样的页面,或者堆栈帧变得如此之大并且写入稀疏以致于跳过保护页面,则会出现潜在的问题。 (保留更多的保护页将有助于以很少的成本防止第二种情况;强制可变大小的堆栈分配——例如,alloca()——总是在将控制权返回给程序之前写入它们分配的空间,从而检测到粉碎的堆栈,将在速度方面以一定的成本阻止第一个,尽管写入可能相当稀疏以保持成本相当低。)

结果

这有什么后果?好吧,操作系统必须对内存管理做正确的事情。 (@Michael 的链接说明了当它出错时会发生什么。)但是让攻击者确定内存分配大小也很危险,因为您不会立即强制写入整个分配。 alloca和 C99 可变大小的数组是一个特别的威胁。此外,我会更怀疑 C++ 代码,因为它往往会进行更多基于堆栈的内存分配;可能没问题,但出现问题的可能性更大。

就个人而言,我更喜欢保持堆栈大小和堆栈帧大小保持较小,并在堆上进行所有可变大小的分配。在某种程度上,这是在某些类型的嵌入式系统上工作以及使用大量线程的代码的遗留问题,但它确实使防止堆栈溢出攻击变得更加简单;操作系统可以可靠地捕获它们,然后攻击者所拥有的只是拒绝服务(烦人,但很少致命)。我不知道这是否是所有程序员的解决方案。

[1] 典型页面大小:32 位系统上为 4kB,64 位系统上为 16kB。检查您的系统文档以了解它在您的环境中的内容。

关于security - 堆栈溢出是安全漏洞吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4104057/

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