【发布时间】:2012-08-19 04:13:16
【问题描述】:
在学习 C 时,我犯了一些错误并打印了未初始化的字符数组的元素。
如果我将数组的大小扩大到相当大,比如 100 万个元素,然后打印内容,结果并不总是用户无法阅读,但似乎包含一些运行时信息。
考虑以下代码:
#include <stdio.h>
main() {
char s[1000000];
int c, i;
printf("Enter input string:\n");
for (i = 0; ( c = getchar()) != '\n'; i++) {
s[i] = c;
}
printf("Contents of input string:\n");
for (i = 0; i < 999999; i++) {
putchar(s[i]);
}
printf("\n");
return 0;
}
只是滚动浏览输出,我发现诸如:
... ?升?? EM> ?????? _ dyldVersionNumber_dyldVersionString_dyld_all_image_infos_dyld_fatal_error_dyld_shared_cache_ranges_error_string__mh_dylinker_header_stub_binding_helper_dyld_func_lookup_offset_to_dyld_all_image_infos__dyld_start__ZN13dyldbootstrapL30randomizeExecutableLoadAddressEPK12macho_headerPPKcPm__ZN13dyldbootstrap5startEPK12macho_headeriPPKcl__ZN4dyldL17setNewProgramVarsERK11ProgramVars__ZN4dyld17getExecutablePathEv__ZN4dyld22mainExecutablePreboundEv__ZN4dyld14mainExecutableEv__ZN4dyld21findImageByMachHeaderEPK11mach_header__ZN4dyld26findImageContainingAddressEPKv P>
还有,
Apple Inc.1&0$U ?0?*?H??ot CA0?"0ple 证书颁发机构10U ?䑩 ??GP??^y?-?6?WLU????Kl??"0?>?P?A?????f?$kУ????z ?G?[?73??M?i??r?]?_???d5#KY?????P??XPg? ?ˬ, op??0??C??=?+I(??ε??^??=?:??? ?b??q?GSU?/A????p??LE~LkP?A ??tb
?!.t??H??cd0??0+https://www.apple.com/appleca/0?+0????Reliance on 任何一方的此证书假定接受当时 适用的标准使用条款和条件,证书 poli?\6?Lx?팛??w??v?w0O????=G7?@?,Ա?ؾ?s???d?yO4آ>?x?k??}9??S? 8??O 01?H??[d?c3w?:,V??!带sO??6?U٧??2B???q?~?R??B$*??M?^c?K ?P??????????7?uu!0?0??0
我相信有一次我的$PATH 环境变量甚至被打印出来了。
未初始化变量的内容是否会带来安全风险?
更新 1
更新 2
因此,从答案中可以清楚地看出这确实存在安全风险。这让我很吃惊。
程序是否无法声明其内存内容受保护以允许操作系统限制对它的任何访问,除了初始化该内存的程序之外?
【问题讨论】:
-
未初始化变量的内容可以做任何事情。有一天,世界将因为其中之一而终结。
-
使用未初始化的变量会导致未定义的行为,所以是的,任何事情都可能发生,安全风险或破坏整个程序或任何可以想象的事情。但很少会发生这样的事情。
-
是的,通常有特殊的内存处理加密版本,可确保值在使用后被清除或永远不会写入交换文件。使用 calloc() 会将内存预置零,并且在大多数 unix 平台上 malloc() 也会这样做。
-
@MartinBeckett 最? unix 平台,我经常使用的 3 不会将 malloc 上的数据归零。但是,它们通常会在将内存页面交给您之前清理它们。
-
@TomTanner,我虽然 gcc/linux 标准库做到了,但显然它比stackoverflow.com/questions/8029584/…更复杂