【问题标题】:C boolean invalid values handling [duplicate]C布尔无效值处理[重复]
【发布时间】:2020-05-18 14:04:18
【问题描述】:

我在一个安全关键的嵌入式 C 项目中,有一个关于检测布尔变量中的内存损坏(例如缓冲区溢出)的讨论。众所周知,在 C 语言中,“布尔”类型实际上是一个 N 位整数,这意味着它可能有 2N-2 个无效值。 例如。如果您将 FALSE 声明为 0 并将 TRUE 声明为 1(通过宏、常量或枚举),则可以说 1 是内存损坏(或错误)的后果。

所以理论上应该可以构造这样的故障捕获代码块:

if (b == TRUE)       { /* Good, do something               */ }
else if (b == FALSE) { /* Good, but don't do anything      */ }
else                 { /* Memory corruption. Deal with it. */ }

或者用 switch-case 来做。状态变量和其他枚举类型是强制性的,但为布尔值做这件事肯定会增加很多代码,我的问题是 - 值得付出努力吗?

【问题讨论】:

  • 考虑到内存损坏也可能用 0 或 1 覆盖 b,我怀疑这是否真的值得。有更好的方法来尝试检测内存覆盖,不需要程序员在他们执行的每一次检查中添加代码
  • 如何检测其他类型变量的损坏,例如int?他们不会同样重要,甚至更重要吗?
  • 一个更好的问题可能是为什么您仍在安全相关软件中使用 C90。它包含许多 C99 解决的危险:“隐式 int”、“struct hack”、可靠的整数除法等。
  • 如果b 被声明为_Bool,C 标准中没有理由相信所示代码足以检测无效位模式。 C 标准没有说明如果在读取 _Bool 对象时,内存中的位不是用于值 0 或 1 的位,会发生什么情况。要检测无效的位模式,您应该使用指针检查内存的内容到unsigned char。如果b 是除_Bool 之外的某个整数类型,那么该代码可能会起作用(尽管C 标准仍然允许填充位和陷阱表示)。
  • 如果您的示例代码中的b 的类型为_Bool(或bool),如果它的值不是0,那么看看您的三个分支中的哪一个被采用会很有趣或 1. 行为可能未定义。所以如果你真的需要检查这样的事情,最好完全避免使用_Bool(或bool)作为此类对象的类型。

标签: c boolean safety-critical


【解决方案1】:

取决于您尝试达到的安全等级。考虑到内存损坏也可能意味着 bit0 发生变化,这将使 TRUE 变为 FALSE,反之亦然,上述示例并不是很安全。

因此,我看到了更多的包装来保护关键变量。

例如将每个变量存储在由变量本身及其补码组成的结构中作为副本。

struct tag_intvar{
    int variable;
    int complement;
};

然后使用 getter/setter 函数授予原子访问权限并执行一致性检查/处理。

int setintvalue(tag_intvar* var, int val){
    if(isconsistent(var)){
        var.variable = val;
        var.complement = ~val;
        return TRUE;
    }
    //... inconsistent... handler
    return FALSE;
}

同时

int isconsistent(tag_intvar* var){
   return (var.variable == ~var.complement)?TRUE:FALSE;
}

【讨论】:

  • 然后......内存在setintvalue的第4行之后被破坏。
  • 是的,有几个安全级别。也许 Mikk 澄清了他正在寻找的安全等级。这来自低端(白色家电,如洗碗机)。这还不如医疗、汽车、航空甚至太空。
  • @sbo - 事实上我正在考虑类似的事情,但可能应该从不间断的部分(中断禁用)调用那些 getter/setter。另一方面,这将是对现有代码的相当大的更新。
  • 是的,它需要尽可能原子化,因此禁用第 3 行和第 4 行的中断。但正如@Groo 所提到的,干扰可能仍然发生在第 3 行和第 4 行之间。但这会被吸气剂识别,这也必须检查。
  • 损坏可能发生在setintvalue(),但是发生在这个位置的可能性很低。因此,您已显着降低了位翻转的可能性。当使用更高功率的设备时,经常会发生位翻转。在这些标准中,错误的概率通常很重要。在这方面,安全性不同于 安全性(和可靠性)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
相关资源
最近更新 更多