カーネル空間からユーザー空間にデータをコピーするときは、copy_to_user()を使用する必要があり、memcpy()を使用するとシステムに問題が発生する、と常に言われています(本やチュートリアルで)。最近誤ってmemcpy()を使用しましたが、問題なく完全に機能しました。memcpy()の代わりにcopy_to_userを使用する必要があるのはなぜですか
私のテストコード(カーネルモジュール)は次のようなものです:
static ssize_t test_read(struct file *file, char __user * buf,
size_t len, loff_t * offset)
{
char ani[100];
if (!*offset) {
memset(ani, 'A', 100);
if (memcpy(buf, ani, 100))
return -EFAULT;
*offset = 100;
return *offset;
}
return 0;
}
struct file_operations test_fops = {
.owner = THIS_MODULE,
.read = test_read,
};
static int __init my_module_init(void)
{
struct proc_dir_entry *entry;
printk("We are testing now!!\n");
entry = create_proc_entry("test", S_IFREG | S_IRUGO, NULL);
if (!entry)
printk("Failed to creats proc entry test\n");
entry->proc_fops = &test_fops;
return 0;
}
module_init(my_module_init);
ユーザースペースアプリから、/proc
エントリを読んでいて、すべて正常に動作しています。
copy_to_user()のソースコードを見ると、これも単純なmemcpy()であり、access_okを使用してポインターが有効かどうかを確認し、memcpyを実行していることがわかります。
したがって、現在の私の理解では、渡すポインタが確実であれば、copy_to_userの代わりにmemcpy()を常に使用できます。
私の理解が正しくない場合は訂正してください。また、copy_to_userが機能し、memcpy()が失敗する例は非常に役立ちます。ありがとう。