有没有办法只读标记一块已分配的内存?

时间:2013-02-18 07:39:09

标签: c++ c memory-management malloc heap-corruption

如果我使用malloc()分配一些内存,有没有办法将其标记为只读。如果有人试图写入,memcpy()会失败吗?

这与错误的api设计相关联,用户错过了使用方法GetValue()返回的const指针,该方法是大内存结构的一部分。由于我们希望避免复制大块内存,因此我们将实时指针返回到具有特定格式的结构化内存中。现在的问题是,有些用户通过直接写入这个内存来找到hack来实现工作,并避免使用SetValue()调用来进行分配并正确处理我们开发的内存二进制格式。虽然有时会破解工作,但有时它会因为用户已覆盖控制标志的错误解释而导致内存访问冲突。

教育用户是一项任务,但现在我们想要让代码失败。

我只是想知道我们是否可以简单地防范这种情况。

类比假设有人从sqlite语句中获取blob列,然后回写它。虽然在sqlite的情况下它没有意义,但在我们的情况下这有点讨厌。

4 个答案:

答案 0 :(得分:59)

在大多数硬件架构上,您只能更改整个memory pages的保护属性;你不能将页面的片段标记为只读。

相关的API是:

您需要确保内存页面不包含任何您不想使其成为只读的内容。要执行此操作,您必须使用malloc()进行过分配,或使用其他分配API,例如mmap()posix_memalign()VirtualAlloc()

答案 1 :(得分:36)

取决于平台。在Linux上,您可以使用mprotect()(http://linux.die.net/man/2/mprotect)。

在Windows上,您可以尝试VirtualProtect()(http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898(v=vs.85).aspx)。我从来没用过它。

编辑: 这不是NPE答案的重复。 NPE最初有不同的答案;它是后来编辑的,并且添加了mprotect()和VirtualProtect()。

答案 2 :(得分:4)

  

错误的api设计,其中用户错过了使用方法GetValue()返回的const指针,该方法是大内存结构的一部分。由于我们希望避免复制大块内存,因此我们将实时指针返回到具有特定格式的结构化内存中

这不是明显错误的API设计。 API是一种契约:您承诺您的类将以特定方式运行,该类的客户端承诺以适当的方式使用API​​。像const_cast这样的诡计是不合适的(在某些情况下,但并非所有情况下都有undefined behaviour)。

如果使用const_cast导致安全问题, 将是错误的API设计。在这种情况下,您必须复制内存块,或重新设计API。 This is the norm in Javadoes not have the equivalent of const(尽管const是Java中的保留字)。

答案 3 :(得分:0)

混淆指针。也就是说,将指针和偏移量返回给客户端,现在他们不能直接使用指针。 每当通过官方API将指针传递给您的代码时,都要减去偏移量并照常使用指针。