【问题标题】:Control effects on padding when copying a C++ POD复制 C++ POD 时对填充的控制效果
【发布时间】:2013-08-30 23:11:39
【问题描述】:

C++ 标准中没有指定填充。它取决于编译器和 CPU。 手动避免填充可能会导致性能问题或更糟。 因此,控制填充中的内容似乎是一种更可行的方法,可以最大限度地减少填充引起的不良副作用,例如安全性。

我想要做的是在对齐的 POD 中填充零。例如一个模板化的函数template<typename T> T zero_padding(T const & pod);

但是有问题。

  1. 如果我们直接进行struct 复制,我们不知道会在填充上做什么,因为 C 标准不保证任何事情。
  2. 我们可以memset 结构,然后按成员进行复制。但它似乎是特定于结构的,对于模板来说并不容易。

所以我似乎找不到一个简单的方法来做到这一点。

【问题讨论】:

  • 不应该阅读填充中的内容,那么它为什么重要呢?您的编译器可能会让您完全禁用填充。
  • @NeilKirk 正如我提到的,出于安全原因。您可以通过这些填充泄漏信息。
  • 你能举一个简单的例子来说明这是怎么发生的吗?我只是好奇。
  • @NeilKirk securecoding.cert.org/confluence/display/seccode/… 这有一些信息。但是解决方案似乎是手动执行或仅使用编译器设置来避免填充。
  • 您必须使用特定的编译器来执行您想要的行为。

标签: c++ alignment padding


【解决方案1】:

这似乎是他们争论的核心

“由于未初始化,填充字节可能包含随机数据(敏感数据)。”

我建议在处理完敏感数据后清除它比让所有其他代码担心包含敏感数据的内存要安全得多。 您希望敏感数据具有受控的生命周期,让它随处可见且不受控制是很弱的。

【讨论】:

    【解决方案2】:

    使用memcpy 复制结构的字节。这将复制填充字节。 memcpy 的合法性是 POD 概念的全部主旨。

    为确保复制操作产生零填充,请确保每个原始对象都使用零填充进行初始化。在执行值初始化时,C++ 确实将 POD 的填充位初始化为零,即如果初始化程序是 = T() 或在 C++11 中,只需 {}。或者,如果您愿意,可以使用memset

    【讨论】:

    • 单独复制成员也是一样的。简单地说,我想要一种将现有结构的填充更改为全零的方法。
    • @WiSaGaN 您最初是如何获得这样一个现有结构的?仅仅有这样一个问题就意味着一个安全问题。 (而且,不,这与您的两个建议不同:复制成员肯定不会复制填充,并且通过简单分配复制整个事物可能会或可能不会;无法保证。)
    • 也许我需要删除我的问题中的安全背景。我只是想知道是否有一种方法可以轻松地将所有填充归零。似乎答案是否定的。
    • @WiSaGaN 不。实际上,我对会员副本的看法是错误的;它可以复制填充,因为编译器可以检测到您正在复制一堆相邻字节,并且还决定复制其他没有语义意义的字节。为了阻止这种情况,您需要在复制到目标之前将数据分散在内存中,使用volatile,或者通过序列化+反序列化之类的操作。另一方面,防止填充永远不为零是非常简单的,至少在实际方面是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 2020-07-10
    • 2018-06-15
    • 2013-11-28
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    相关资源
    最近更新 更多