c - C中未初始化的局部变量中包含的值到底是什么?

标签 c linux security process stack

如果我们在 C 中有一个函数,其中有一个简单的单元化 ìnt 变量,我们知道这个变量可能并不总是初始化为零。相反,它可能包含一些“垃圾”值。

我的问题是:究竟什么可以代表那个值?可能是之前终止的进程留下的一些信息(未释放的内存)?

如果是,那么这不是一个极其重大的安全漏洞吗?因为这样一来,任何进程都可以读取与当前进程使用相同地址空间的进程留下的信息(密码、 token 等)。

我的假设是,对于每个新进程,内核都会将分配给该新进程的内存清零(至少是堆栈),然后将可执行文件加载到内存中。这些“垃圾”值实际上是由当前进程加载过程生成的值(因此无法从使用相同进程的其他进程访问任何剩余数据地址空间)。

我正在和一些人争论这个话题,我真的想要一个清晰而全面的答案(我相信有一个)。我们假设内核是基于 debian/centos 的。很高兴知道不同内核/操作系统的行为是否存在差异。

恭敬地感谢您。

最佳答案

这应该分为两个问题:

  • C 标准对未初始化对象的值有何规定?
  • 调用 main 时内存中有什么?

第一个问题在其他 Stack Overflow 问题和答案中进行了讨论。完整的答案很复杂,涉及各种情况的讨论,而且这个问题似乎并没有特别问这个问题,所以我将把它留给其他 Stack Overflow 问题。对于这个问题,只要说使用未初始化对象的值容易出现未定义的行为就够了。此外,这不仅仅是因为对象的内存可能有麻烦的值,而是因为 C 标准允许 C 实现以各种方式将读取未初始化值的程序视为行为不端的程序,然后优化可以进一步破坏程序.

就内存中的内容而言(假设我们有一种支持的方法来检查它,也许通过使用汇编语言而不是 C),那么每个提供任何类型的安全删除(或以其他方式初始化)内存的多用户系统在将其提供给进程之前。正如问题所设想的那样,调用 main 时内存中的任何值都是加载过程或操作系统初始化的结果。 (请注意,加载过程的结果包括常量数据和程序文本的加载——所以我们希望在那里找到定义的值——以及加载代码完成工作后遗留下来的任何数据——它的变量等等。 )

这个问题需要一个明确的答案,所以让我明确一点:为用户进程提供安全性的操作系统必须在使内存可供另一个进程使用之前从内存中删除先前进程的数据过程。安全不能通过信任程序不检查给定的内存并随心所欲地使用它来提供。

不打算由不受信任的用户共享的基本系统当然可以在创建新进程并为它们分配内存时跳过内存的初始化。

关于c - C中未初始化的局部变量中包含的值到底是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52616928/

相关文章:

c - fread 或 fwrite 给出 "Bad file number"

奇怪的数组覆盖

c - C 中的指针数学问题

linux - 通过 AWS CLI 进行 AWS 转录

linux - 无法 dlopen 加载模块 '/usr/lib/pa20_64/libpthread.1',因为它包含线程特定数据

PHP登录 - 密码输入 - 特殊字符? - Centos 5 系统

创建文件并使用系统调用操作向其中写入随机字符

linux - 内核日志 "file descriptor"用于选择吗?

java - 使用 CipherOutputStream + AES 将字符串写入文件

ios - iOS 6 是否支持 OpenSSL?