52

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

这与错误的 api 设计有关,在这种设计中,用户错误地使用了一个方法返回的 const 指针,该方法 GetValue()是大内存结构的一部分。由于我们希望避免复制大块内存,因此我们在具有特定格式的结构化内存中返回实时指针。现在的问题是,一些用户发现黑客可以通过直接写入该内存并避免 SetValue() 调用来进行分配并正确处理我们开发的内存二进制格式。尽管有时会发生黑客攻击,但有时会由于对已被用户覆盖的控制标志的错误解释而导致内存访问冲突。

教育用户是一项任务,但现在让我们说我们希望那里的代码失败。

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

打个比方,假设有人从 sqlite 语句中得到一个 blob 列,然后写回它。虽然在 sqlite 的情况下它没有意义,但在我们的情况下这有点发生。

4

4 回答 4

65

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

相关的 API 是:

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

于 2013-02-18T07:43:06.470 回答
37

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

于 2013-02-18T07:44:26.280 回答
5

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

显然不是一个错误的 API 设计。API 是一种契约:您承诺您的类将以特定方式运行,该类的客户承诺以适当的方式使用 API。像这样的肮脏技巧const_cast是不恰当的(在某些但并非所有情况下,具有未定义的行为)。

如果使用导致安全问题,那将是错误的 API 设计。const_cast在这种情况下,您必须复制内存块,或重新设计 API。这是 Java 中的规范,它没有等效于const(尽管const是 Java 中的保留字)。

于 2013-02-19T13:08:12.707 回答
2

混淆指针。即返回给客户端的指针加上一个偏移量,现在他们不能直接使用指针。每当指针通过官方 API 传递给您的代码时,减去偏移量并照常使用指针。

于 2019-07-09T23:02:40.747 回答