在 LDD3 的示例中,access_ok()
放置在内核模块的ioctl
方法的开头,以检查从用户空间传递的指针是否有效。当用户空间应用程序调用{{1}}系统调用时,它是正确的,并将其传递给变量的地址。但是,在某些情况下,使用值而不是指针作为第三个参数调用ioctl()
系统调用,最后调用内核模块中ioctl()
的第二个参数。
我试图传递一个整数作为access_ok()
的第二个参数,它运行正常。没有报告错误。但我不确定这种用法是否正确?
例如,如果我在用户空间中调用access_ok()
,其第三个参数为“3”。然后,在ioctl()
的{{1}}方法中,ioctl()
将收到struct file_operations
作为第二个参数。因为access_ok()
需要一个指针,所以它将3
转换为用户空间指针。相反,这是错误的......
答案 0 :(得分:0)
用户空间程序可以为您提供任意随机值作为指针,因此access_ok()
必须能够处理任何随机值。
因此,使用非指针值调用access_ok()
绝对可以。
但是,除非您实际上尝试访问该内存位置,否则调用access_ok()
完全没有意义。
(就此而言,如果可能的话,您应该避免access_ok()
,只检查实际的用户空间访问(get_user()
等)是否有错误。)
答案 1 :(得分:0)
实际上,access_ok
的检查很粗糙。函数描述(在源文件中)说:
请注意,根据架构,这个功能可能只是 检查指针是否在用户空间范围内 - 在调用之后 此功能,内存访问功能仍可返回-EFAULT。
,根据源arch/x86/include/asm/uaccess.h
,在x86 access_ok
上只检查给定地址指向 lower 区域(因为除了上层区域之外的内核)。因此,对于等于true
的地址,它会返回3
。
copy_from_user
/ copy_to_user
返回关于用户内存可访问性的最终判决。