我可以通过错误使用指针分配和值更改来破坏我的 OS 吗?

Can I corrupt my OS via incorrect usage of pointer assignments & value changes?

如标题所示,我是 C++ 的新手,并且在 Code::Blocks IDE 上练习了许多不同的程序。我今天想到了这个问题,但似乎无法得到准确的答案。我是否会因指针使用不当而无意中损坏 OS 上的数据?更详细一点,将:

char *p ; //creating uninitialized pointer with a random address; 
          //let's assume it's the address to a variable within a valid file?
*p = 'G' ;

//or

int *p ; 
*p = 2 ;

可以在我的 IDE/compiler 文件中执行此操作可能会损坏某些数据,例如:

  1. 操作系统文件 - 也许核心操作系统文件和值从 1 ---> 2 的变化可能导致外部设备的物理损坏。

    AND/OR

  2. C: 驱动器上未打开的随机文件 - 例如,一个重要的文件已被 256 位加密;单个值的更改将使文档解密几乎不可能,从而导致重要文档完全损坏且无法恢复。直到几个月后,当我尝试打开文件但在解密过程中收到一条错误消息时,我才意识到这种损坏。

    AND/OR

  3. 使用临时内存打开程序 - 例如我目前正在 运行 一个 cold-storage 比特币钱包程序(一个糟糕的程序)并且假设该程序已经打开动态分配的加密文件。该文件包含访问 cold-storage 比特币中的 10 万美元所需的备份密钥验证文件;文件内字符的更改将永久损坏文件,基本上会导致恢复密钥备份数据丢失。因此,如果我忘记了我的比特币钱包密码,尝试使用恢复功能将失败,并导致永久损失一栋漂亮房子的首付。

所以这些是一些示例,我想知道是否可以通过摆弄指针、尝试学习 C++ 来实现它们中的任何一个。我不想现在或将来不小心造成上述任何情况(也许正在做一个更大的项目,上面的情况会带来灾难),所以请让我知道这些情况中的任何一种是否可能(尽管非常发生的可能性很小,但仍有可能)。如果有可能使用无效指针破坏 OS 内的数据,扩展内存泄漏等,请您解释一下防止上述情况的动态。

Can I corrupt my OS via incorrect usage of pointer assignments & value changes?

很可能不会。

在现代桌面 OSes 和服务器 OSes 中,进程使用的内存 space 是虚拟的。访问无效内存会导致未定义的行为,但这不允许进程更改它无权访问的 files/memory。

您可能会破坏 OS 如果:

  1. 您运行程序具有root/admininstrative权限,并且
  2. 你 modify/delete 文件是 OS 到 运行 所必需的文件。

由于缺乏经验,我无法评论在不为进程使用虚拟内存的平台上会发生什么。

一个设计得当的现代 OS 应该被设计成你不能通过 运行 编写你编写的程序来破坏 OS。注意应该;查看 CVE list 了解许多并非如此的示例。

大多数 OS 您可能用于开发的威胁模型无法保护您的个人文件免受您 运行 的程序的侵害。参见 XKCD 1200。但是,您可以采取预防措施,例如:

  • 运行作为独立用户ID的程序
  • 或运行在虚拟机中安装程序
  • 或运行在chroot环境中安装程序
  • 或运行在强制访问控制生效时关闭程序,防止程序写入指定目录外的文件或打开网络套接字(如 SELinux)
  • 并通过正确理解程序并避免此类错误

以下注意事项也降低了风险:

  • 未初始化的指针很可能为零,因此为空,因此在您使用它时会导致段错误;或者如果设置为 "random" 值,可能指向未映射的内存,结果相同
  • 即使您确实更改了后续 std::fstream::open(或来自 POSIX 的 open,或来自 C stdio fopen 的参数 API,或其他类似的 OS 特定函数),您实际上不太可能将其更改为与其他程序使用的文件名实际匹配的内容。更有可能在文件名中引入垃圾字节,或者直接 运行 对其进行分类;除非你的程序已经在做类似 "enumerate all files under my home directory, and open each one".
  • 的事情

顺便说一句,在很多情况下,您提供的将 "random" 位内存设置为 "random" 的代码可能与 "random" 相去甚远。例如,每次程序 运行 时它可能都是相同的值。一些更好的(虽然是 C,而不是 C++)替代品...

   // #1
   char *p = rand();
   *p = rand();

   // #2
   FILE * randomDevice = fopen("/dev/urandom", "r");
   char *p;
   fread(&p, sizeof(char *), 1, randomDevice);
   fread( p, sizeof(char),   1, randomDevice);