指向常数的指针

时间:2016-03-11 09:33:55

标签: c pointers

众所周知,通过引用将参数(特别是如果它们具有大型结构)传递给函数是一种很好的做法。并且要应用"最小特权"的原则,如果该函数不应该改变这些传递变量的值,那么我们需要将它们的引用作为指向常量的指针传递。 我的问题是,作为指向常量的指针传递不能阻止更改函数中的值(您可以考虑附加的代码),那么我们如何防止这种做法呢?

void print(const int *ptr) {
    printf("%d\n", *ptr);
    int * p = ptr;
    *p = 11;
}

我在这里不讨论是否可以通过指针改变常量的值。我知道我们可以。但我的问题是如何防止这种做法强制执行最小特权原则?否则如果我们可以轻松地玩它,如上面的代码所示,将引用作为指针传递给常量有什么用?

3 个答案:

答案 0 :(得分:1)

由于C是不受管理的,所以你无法做任何事情来防止本地调用的C函数搞乱外部的东西。即使语言以某种方式强制执行“const-ness”,print()也可以做许多其他事情,如果它是如此倾向,那将违反最小特权。

相反,C提供了合作实施更安全程序的方法。在这种情况下,print()必须通过声明p作为指向const int的指针来进行合作。

作为比较点:从安全角度来看,C调用者和C函数属于同一个信任边界。具体来说,它们属于同一个流程(因此不包括跨越信任边界的调用,如IPC或RPC,来自此讨论)。在给定的信任边界内,所有参与者(几乎)总是拥有相同的特权集。 “特权”在这里意味着外部授予执行行动的权利,而不是自我施加的限制。

同一信任边界内的参与者“免费”互相篡改。如果功能A篡改了来电者B,那么没有比B自身行动更大的威胁。 B可以做同样的事情,无论是单独行动还是由A做某事。从安全角度来看,A和B同样享有特权。

因此,在C调用者/函数的情况下,考虑“最小自我允许行为的原则”而不是“最小特权原则”可能会更有帮助。

答案 1 :(得分:1)

此代码int * p = ptr;格式错误,无效C.

根据简单分配规则(6.5.16.1),强调我的:

  

以下其中一项应成立:

     

/ - /

     
      
  • 左操作数具有原子,限定或非限定指针类型,并且(考虑左值操作数在左值后的类型)   转换)两个操作数都是限定或不合格的指针   兼容类型的版本,和左侧指向的类型   右侧所指示的所有类型的限定符;
  •   

限定符表示类型限定符,例如constvolatile。代码中的左操作数与右操作数没有相同的限定符,因此不应编译。

答案 2 :(得分:0)

As"函数总是可以转换指针以去除任何const限制" (见jotik的评论),你无法通过语言来阻止它。

剩下的就是将其写在您公司的编码标准中,并明确地将其包含在代码审查中,以找出程序员仍在执行此操作的位置。

当发现这种用途时,可以调查原因。也许程序员是对的,应该更改函数签名(或引入新函数)。

相关问题