您应该在用户空间指针上使用strlen_user()而不是strlen() – 并且您应该只调用一次,并保持结果(否则,您有潜在的内核漏洞,因为第二个用户空间线程可能会更改缓冲区当你正在努力的时候).
或者,您可以使用strncpy_from_user().
除此之外,kmalloc看起来还不错.
(但实际上,正如ephemient所说,你应该重新考虑整个方法并使用count参数而不是将输入视为字符串).
由于您不能依赖写入以nul结尾的字符串的文件的数据,因此您需要在数据旁边保留data_len长度参数.那么你的读/写实现将沿着这些方向:
static char *data = NULL;
static size_t data_len;
static DEFINE_MUTEX(data_mutex);
static ssize_t memo_read(struct file *f, char __user *buf, size_t count, loff_t *f_pos
{
ssize_t retval = 0;
char *start;
mutex_lock(&data_mutex);
if (!data)
{
retval = -EINVAL; /* Or whatever you want to do here... */
goto out;
}
if (*f_pos >= data_len)
goto out; /* EOF */
start = data + *f_pos;
retval = data_len - *f_pos;
if (retval > count)
retval = count;
if (copy_to_user(buf, start, retval))
{
retval = -EFAULT;
goto out;
}
*f_pos += retval;
out:
mutex_unlock(&data_mutex);
return retval;
}
static ssize_t memo_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
ssize_t retval = -ENOMEM;
mutex_lock(&data_mutex);
if (data)
kfree(data);
data = kmalloc(count, GFP_KERNEL);
if (!data)
goto out;
if (copy_from_user(data, buf, count))
{
kfree(data);
retval = -EFAULT;
goto out;
}
*f_pos = count;
retval = count;
data_len = count;
out:
mutex_unlock(&data_mutex);
return retval;
}