編輯:我還沒有一個很好的答案,但爲什麼我在這裏失敗......所以讓我稍微改寫一下。我甚至需要verify_area()檢查嗎?那是什麼意思?我已經測試了我的結構成功通過這個ioctl的事實,我正在考慮刪除失敗的檢查,但我並不是100%在做什麼。思考? 編輯完access_ok爲什麼這個ioctl失敗
我正在更新一些舊的Linux內核驅動程序和測試的同時,一分出來我得到一個失敗似乎很奇怪我。在這裏,我們去:
我在用戶空間提供簡單的ioctl調用:
Config_par_t cfg;
int ret;
cfg.target = CONF_TIMING;
cfg.val1 = nBaud;
ret = ioctl(fd, CAN_CONFIG, &cfg);
的Config_par_t在can4linux.h文件中定義(這是帶有uCLinux的CAN驅動器):
typedef struct Command_par {
int cmd; /**< special driver command */
int target; /**< special configuration target */
unsigned long val1; /**< 1. parameter for the target */
unsigned long val2; /**< 2. parameter for the target */
int error; /**< return value */
unsigned long retval; /**< return value */
} Command_par_t ;
在物聯網核心方面,ioctl函數調用verify_area,這是失敗的過程:
long can_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
void *argp;
long retval = -EIO;
Message_par_t Message;
Command_par_t Command;
struct inode *inode = file->f_path.dentry->d_inode;
argp = &Message;
Can_errno = 0;
switch(cmd) {
case CONFIG:
if(verify_area(VERIFY_READ, (void *) arg, sizeof(Command_par_t))) {
return(retval);
}
現在我知道,verify_area()已不再使用,所以我在頭文件中使用這個宏更新它access_ok:
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
#define verify_area(type, addr, size) access_ok(type, addr, size)
#endif
我在x86平臺上,所以我敢肯定,實際access_ok ()宏被稱爲是這裏定義的一個在/usr/src/linux/arch/x86/include/asm/uaccess.h:
#define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0))
#define __range_not_ok(addr, size) \
({ \
unsigned long flag, roksum; \
__chk_user_ptr(addr); \
asm("add %3,%1 ; sbb %0,%0 ; cmp %1,%4 ; sbb $0,%0" \
: "=&r" (flag), "=r" (roksum) \
: "1" (addr), "g" ((long)(size)), \
"rm" (current_thread_info()->addr_limit.seg)); \
flag; \
})
我想對我來說這看起來像它應該工作。任何想法爲什麼我會從這個verify_area獲得1個返回,如果檢查?或者有關我如何才能縮小問題的想法?
if(verify_area(VERIFY_READ, (void *) arg, sizeof(Command_par_t))) {
呃,抱歉,我的最後一句話是不正確的。 access_ok的結果是1 ...輕微的打字造成了很大的差異...我會更新我的問題。 – Mike
好吧,我能找到答案幫助爲自己克服這一點,是的,你是正確的一切工作。這個補丁文件幫助我理解:'-if(verify_area(VERIFY_WRITE,oact,sizeof(* oact))||'vs new:'+ if(!access_ok(VERIFY_WRITE,oact,sizeof(* oact))||'返回翻轉。 – Mike