0

我有一个设备驱动程序,它允许用户空间应用程序使用 ioctl 机制执行各种操作。作为初始 ioctl 调用的一部分返回的是一个句柄,该句柄应该对应用程序在其他 ioctl 调用中提供的用户空间应用程序是不透明的。

在驱动程序内部,句柄是内核空间中某些控制/上下文块的地址。如果可以信任应用程序忠实地传回返回的句柄,那么一切都很好。担心的是如果应用程序是恶意的并传回一些任意句柄,然后驱动程序将其转换为适当的指针类型并取消引用它。

我正在考虑的一项健全性检查是与 PAGE_OFFSET 进行比较,如果小于则拒绝(以确保地址至少指向内核内存)。如果我认为在内核空间中不合法的页面错误怎么办?一个简单的方案可能是检查句柄是否先前已返回到用户空间,但搜索的开销可能很高(因为可能有很多这样的句柄)。

是否有一种强大而有效的方法来验证句柄?任何帮助表示赞赏。

谢谢。

4

2 回答 2

2

永远不要接受来自不受信任程序的指针。
这对您的代码和其他代码(例如,使用您窥视进程不得访问的内存)造成的攻击没有止境。

有很多方法可以验证它,但它们很复杂或很昂贵。例如:
1. 将所有手柄放在一个数组中。验证指针是否在数组内,并且正确对齐。但是你可以使用数组索引作为句柄。
2. 扫描您的句柄数据库并将指针与用户提供的指针进行比较。在数据库中找到之前不要取消引用句柄。但同样,使用一些 ID 进行查找,而不是指针,可以简化它。

您可能需要验证更多的事情:
1. 正如 Alex 评论的那样,如果有几种可能的句柄类型,请验证您是否获得了正确的类型(即 prevent h = get_handle_typeA(); use_handle_typeB(h))。
2. 确保每个进程只使用它创建的句柄。因此,一个进程将无法猜测句柄值并希望捕捉到一个有效值。

于 2012-05-17T06:56:14.773 回答
0

为什么你甚至需要一个把手?打开的文件一个句柄,您可以在其中存储自己的私有数据,例如:

static long your_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
      struct your_struct *p = f->private_data;
      ...
于 2012-05-25T07:32:21.877 回答