【问题标题】:does clang/gcc optimize password variable clearing functionclang/gcc 是否优化密码变量清除功能
【发布时间】:2015-01-25 23:15:14
【问题描述】:

我们担心恶意程序会尝试从 RAM 中读取密码。所以我们写了一个函数来覆盖密码变量,然后释放它。我们担心的是,像 clang 或 gcc 这样的智能编译器会优化这个函数中的代码。该函数将字符串中的每个字符都更改为空字节,然后释放变量。

void free_pword(char* pword) {
    char* pword_original = pword;
    char c;

    while ((c = *(pword++))) {
        *pword = '\0';
    }

    free(pword_original);
}

现在我们的问题。我们需要这样做吗?如果不是,为什么?如果我们确实需要这样做,我们如何确保覆盖不会被优化掉?

########### 编辑 1:(2015 年 2 月 11 日)

来自未来的亲爱的人们:这是我们迄今为止所发现的......

我查看了原始汇编代码(来自 gcc)以确定代码是否被优化掉了,但事实并非如此。我决定添加 volatile 以防优化器在更新中发生变化。

测试的 gcc 版本。

$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix

我没有做出并接受我自己的答案,因为我不能 100% 确定这对所有编译器都是安全的。编译器方面的专家或许可以肯定地回答。

如果您需要像我们在释放密码之前那样安全地删除密码,请使用您的编译器测试此功能并查看原始程序集。您不必了解程序集,只需确保调用了 ___bzero 函数 (memset) 和 _free 函数。

当前工作版本:

void free_pword(char * pword) {
    //instead of changing the argument to the function, I added a volatile variable
    //this was I don't have to change the calls to this function to remove warnings
    char volatile * volatile_pword = pword;
    memset((char *)volatile_pword, 0, strlen((char *)volatile_pword));
    free((char *)volatile_pword);
}

【问题讨论】:

  • 反对优化,想到的第一个锤子是volatile。然后你可以考虑微妙之处。
  • 如果你在一个单独的翻译单元中调用一个函数来做密码的转换,它需要更多的编译器来发现这个函数可以被删除。使用memset() 或显示的代码可能会导致优化器忽略切换代码。
  • 顺便说一句,原始代码有一个错误 - 它不会覆盖密码中的第一个字符。 pword 已在 *pword = '\0'; 执行时递增。

标签: c gcc clang


【解决方案1】:

编译器完全有可能优化对memset 的调用。这就是为什么有像 memset_s (C11) 和 explicit_bzero (BSD) 这样的函数来安全地擦除一块内存。

我也认为使用 volatile 函数指针比强制转换为指向 volatile 的指针更可靠:

void *(*volatile forced_memset)(void *, int, size_t) = memset;

更多技巧,如插入asm 语句或内存屏障,可以在此great thread on the musl mailing list 中找到。在那里,您还可以找到指向这个有趣的 post on how to portably test whether any of these approaches work 的指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多