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

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

这被连接到一个错误的APIdevise,用户无法使用由大型内存结构的一部分GetValue()方法返回的const指针。 由于我们要避免复制大量内存,因此我们将活动指针返回到特定格式的结构化内存中。 现在的问题是,有些用户发现通过直接写入这个内存到达那里工作的东西,避免SetValue()调用分配和正确地交付我们开发的内存二进制格式。 尽pipe在某些时候黑客可能会工作,但是由于控制标志的解释不正确而被用户覆盖,导致内存访问冲突。

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

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

对于比喻,假设有人从sqlite语句中获得一个blob列,然后回写给它。 虽然在sqlite的情况下,这是没有道理的,但在我们的情况有点happing。

在大多数硬件体系结构中,只能更改整个内存页面上的保护属性; 您不能只读标记一个页面的片段。

相关的API是:

  • Unix上的mprotect() ;
  • Windows上的VirtualProtect()

您将需要确保内存页面不包含任何您不想使其为只读的内容。 为此,您必须使用malloc()或者使用不同的分配API,例如mmap()posix_memalign()VirtualAlloc()

取决于平台。 在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()。

一个错误的apidevise,用户无法使用由大型内存结构的一部分GetValue()方法返回的const指针。 由于我们要避免复制大块内存,因此我们将活动指针返回到特定格式的结构化内存中

显然不是一个错误的APIdevise。 API是一个契约:你承诺你的类将以一种特定的方式行事,类的客户承诺以正确的方式使用API​​。 肮脏的技巧,如const_cast是不正确的(在一些,但不是所有的情况下,有未定义的行为 )。

如果使用const_cast会导致安全问题,那么这是错误的APIdevise。 在这种情况下,您必须复制大块内存,或者重新deviseAPI。 这是Java中的常态 ,它不具有const的等价物 (尽pipeconst是Java中的保留字)。

Interesting Posts