Не забывайте kfree(data)
в ваших случаях ошибки ...
В любом случае, buf
- это указатель на пользовательскую память, поэтому НЕ вызывайте strlen(buf)
.Сначала вы должны copy_from_user
.Почему бы не
data = kmalloc(count);
copy_from_user(data, buf, count);
?
Ваш обработчик чтения предполагает, что data
является строкой с нулевым символом в конце.Когда вы использовали массив, это могло произойти случайно, но вы никогда не гарантировали этого в своем обработчике записи.Я предполагаю, что copy_to_user
терпит неудачу.
Вот рабочий пример модуля "memo", который я только что написал, используя kmalloc
:
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/uaccess.h>
static char *data;
static size_t len;
static ssize_t
memo_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
ssize_t copy_len = min(len - min(len, *ppos), count);
ssize_t retval;
if (copy_to_user(buf, data + *ppos, copy_len)) {
retval = -EFAULT;
goto out;
}
*ppos += copy_len;
retval = copy_len;
out:
return retval;
}
static ssize_t
memo_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
ssize_t retval;
char *newdata;
newdata = kmalloc(count, GFP_KERNEL);
if (!newdata) {
retval = -ENOMEM;
goto out;
}
if (copy_from_user(newdata, buf, count)) {
retval = -EFAULT;
goto out;
}
kfree(data);
data = newdata;
newdata = NULL;
retval = len = count;
out:
kfree(newdata);
return retval;
}
static const struct file_operations memo_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = memo_read,
.write = memo_write,
};
static struct miscdevice memo_misc = { MISC_DYNAMIC_MINOR, "memo", &memo_fops };
static int __init memo_init(void)
{
int result;
result = misc_register(&memo_misc);
if (result < 0)
return -ENODEV;
return 0;
}
static void __exit memo_exit(void)
{
misc_deregister(&memo_misc);
kfree(data);
return;
}
module_init(memo_init);
module_exit(memo_exit);
MODULE_AUTHOR("ephemient");
MODULE_LICENSE("GPL");
Конечно, этоотсутствует блокировка и другие меры предосторожности, но я надеюсь, что это поможет.