宏"access_ok"最近取消的第一个参数如何替换?
How to replace the recently abolished first parameter of macro "access_ok"?
正在尝试将老式驱动程序从内核 2.6 合并到最新的内核 5.8。
并遇到以下错误:
macro "access_ok" passed 3 arguments, but takes just 2
access_ok
是在asm/uaccess.h
中定义的宏
这是代码片段:
#include <asm/uaccess.h>
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
if (err) return -EFAULT;
我做了一些谷歌搜索,但他们都告诉我切换到支持接受 3 个参数的 access_ok
的较低版本内核,显然这没有解决我的问题。
所以我想知道我可以用哪个宏替换 access_ok
?
根据 Torvalds' reply,type
参数已从 access_ok()
函数(或宏)中删除,您唯一需要做的就是将提到的代码片段修改为最新的内核(现在是 5.8),就是简单地删除第一个参数(例如 VERIFY_WRITE
或 VERIFY_READ
)
这里是修改后的片段
#include <asm/uaccess.h>
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok((void __user *)arg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = !access_ok((void __user *)arg, _IOC_SIZE(cmd));
if (err) return -EFAULT;
我包含以下兼容性代码:
#include <linux/version.h>
/*
* <linux/uaccess.h> was added in kernel version 2.6.18, and should be
* included in preference to <asm/uaccess.h>. In particular, copy_to_user()
* and copy_from_user() were moved to <linux/uaccess.h> in kernel version
* 4.12.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
#include <linux/uaccess.h>
#else
#include <asm/uaccess.h>
#endif
/*
* Kernel 5.0 removed VERIFY_READ and VERIFY_WRITE and removed the first
* parameter of access_ok() which was set to VERIFY_READ or VERIFY_WRITE.
* That has been redundant since kernel 2.5.70, and even then it was only
* checked for kernels that support old 386 processors.
*
* Get rid of the first parameter and always pass VERIFY_WRITE for kernels
* prior to 5.0. This will fail for old 386 processors on pre-2.5.70
* kernels if the memory region is not in fact writeable.
*/
#ifdef VERIFY_WRITE
/* Pre 5.0 kernel. */
static inline int _kcompat_access_ok(unsigned long addr, size_t size)
{
/* Always use VERIFY_WRITE. Most architectures ignore it. */
return access_ok(VERIFY_WRITE, addr, size);
}
/* Redefine access_ok() to remove first parameter. */
#undef access_ok
#define access_ok(addr, size) _kcompat_access_ok((unsigned long)(addr), (size))
#endif
然后将代码中所有旧的三参数调用更改为 access_ok
以省略第一个参数。
对于仍然需要删除参数的 5.0 之前的内核,此兼容性代码始终将其设置为 VERIFY_WRITE
。这并不重要,因为参数值自内核版本 2.5.70 以来一直是多余的,即便如此,它也只检查支持旧 386 处理器的内核。
正在尝试将老式驱动程序从内核 2.6 合并到最新的内核 5.8。
并遇到以下错误:
macro "access_ok" passed 3 arguments, but takes just 2
access_ok
是在asm/uaccess.h
这是代码片段:
#include <asm/uaccess.h>
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
if (err) return -EFAULT;
我做了一些谷歌搜索,但他们都告诉我切换到支持接受 3 个参数的 access_ok
的较低版本内核,显然这没有解决我的问题。
所以我想知道我可以用哪个宏替换 access_ok
?
根据 Torvalds' reply,type
参数已从 access_ok()
函数(或宏)中删除,您唯一需要做的就是将提到的代码片段修改为最新的内核(现在是 5.8),就是简单地删除第一个参数(例如 VERIFY_WRITE
或 VERIFY_READ
)
这里是修改后的片段
#include <asm/uaccess.h>
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok((void __user *)arg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = !access_ok((void __user *)arg, _IOC_SIZE(cmd));
if (err) return -EFAULT;
我包含以下兼容性代码:
#include <linux/version.h>
/*
* <linux/uaccess.h> was added in kernel version 2.6.18, and should be
* included in preference to <asm/uaccess.h>. In particular, copy_to_user()
* and copy_from_user() were moved to <linux/uaccess.h> in kernel version
* 4.12.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
#include <linux/uaccess.h>
#else
#include <asm/uaccess.h>
#endif
/*
* Kernel 5.0 removed VERIFY_READ and VERIFY_WRITE and removed the first
* parameter of access_ok() which was set to VERIFY_READ or VERIFY_WRITE.
* That has been redundant since kernel 2.5.70, and even then it was only
* checked for kernels that support old 386 processors.
*
* Get rid of the first parameter and always pass VERIFY_WRITE for kernels
* prior to 5.0. This will fail for old 386 processors on pre-2.5.70
* kernels if the memory region is not in fact writeable.
*/
#ifdef VERIFY_WRITE
/* Pre 5.0 kernel. */
static inline int _kcompat_access_ok(unsigned long addr, size_t size)
{
/* Always use VERIFY_WRITE. Most architectures ignore it. */
return access_ok(VERIFY_WRITE, addr, size);
}
/* Redefine access_ok() to remove first parameter. */
#undef access_ok
#define access_ok(addr, size) _kcompat_access_ok((unsigned long)(addr), (size))
#endif
然后将代码中所有旧的三参数调用更改为 access_ok
以省略第一个参数。
对于仍然需要删除参数的 5.0 之前的内核,此兼容性代码始终将其设置为 VERIFY_WRITE
。这并不重要,因为参数值自内核版本 2.5.70 以来一直是多余的,即便如此,它也只检查支持旧 386 处理器的内核。