正如标题所暗示的那样,我是C++新手,并在Code::Blocks IDE上练习许多不同的程序。我今天想了想,似乎无法得到准确的答案。我是否会因不当使用指针而无意中损坏操作系统上的数据?更详细一点,将:
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/编译器文件中执行此操作可能会损坏某些数据,例如:
操作系统文件 - 也许核心操作系统文件和值从 1 ---> 2 的更改可能会导致外部设备的物理损坏。
和/或
C: 驱动器上未打开的随机文件 - 例如,假设一个经过 256 位加密的重要文件;单个值的更改将使解密文档几乎不可能,从而导致完全损坏且无法恢复的重要文档。直到几个月后,当我尝试打开文件但在解密过程中收到错误消息时,我才会意识到这种损坏。
和/或
利用临时内存的开放程序 - 例如,假设我目前正在运行一个冷存储比特币钱包程序(一个蹩脚的程序),并且作为假设该程序打开了一个动态分配的加密文件。此文件包含访问 10 万美元的冷存储比特币所需的备份密钥验证文件;文件中字符的更改将永久损坏文件,并基本上导致恢复密钥备份数据丢失。因此,如果我忘记了我的比特币钱包密码,尝试使用恢复功能将失败,并导致永久丢失漂亮房子的首付。
所以这些是一些例子,我想知道它们中的任何一个是否可以通过弄乱指针,试图学习C++。我不想现在或将来意外导致上述任何情况(也许正在从事一个更大的项目,上述情况会带来灾难),所以请让我知道这些情况是否可能(尽管发生的可能性非常低,但仍然可能)。另外,如果可能使用无效指针损坏操作系统中的数据,扩展内存泄漏等,请您解释防止上述情况的动态。
应该设计一个设计得当的现代操作系统,以便您不会通过运行您编写的程序来损坏操作系统。注意应该;查看 CVE 列表,了解许多情况并非如此的示例。
您可能在其上进行开发的大多数操作系统的威胁模型不会保护您的个人信息免受您运行的程序的侵害。参见 XKCD 1200。但是,您可以采取预防措施,例如:
- 以单独的用户 ID 身份运行程序
- 或在虚拟机中运行程序
- 或在
chroot
环境中运行程序 - 或在强制访问控制生效时运行程序,以防止程序写入指定目录之外的文件或打开网络套接字(如 SELinux)
- 并通过正确理解程序并避免此类错误
风险还可以通过以下注意事项来缓解:
- 未初始化的指针可能为零,因此为 null,因此在使用它时会导致分段错误;或者如果设置为"随机"值,则可能指向未映射的内存,结果相同
- 即使您确实更改了后续
std::fstream::open
的参数(或来自 POSIX 的open
参数,或从 C stdio APIfopen
,或其他一些类似的特定于操作系统的功能),您也不太可能实际将其更改为与其他程序使用的文件名实际匹配的内容。更有可能在文件名中引入垃圾字节,或者直接截断它;除非您的程序已经在执行诸如"枚举我的主目录下的所有文件,并打开每个文件"之类的操作。
顺便说一下,在很多情况下,您提供的将"随机"内存位设置为"随机"的代码可能远非"随机"。例如,每次运行程序时,它可能都是相同的值。一些更好的(虽然是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);
我可以通过不正确地使用指针赋值和值更改来损坏我的操作系统吗?
很可能不是。
在现代桌面操作系统和服务器操作系统中,进程使用的内存空间是虚拟的。访问无效内存会导致未定义的行为,但这不允许进程更改它无权访问的文件/内存。
在以下情况下,您可能会损坏操作系统:
- 您使用根/管理权限运行程序,并且
- 修改/删除操作系统正常运行所需的文件。
由于缺乏经验,我无法评论不使用虚拟内存进行进程的平台上会发生什么。