加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

如何在Linux内核中为char *类型字符串分配内存?

发布时间:2020-12-13 19:27:17 所属栏目:Linux 来源:网络整理
导读:我正在尝试为char *分配一些内存,如下所示. static ssize_t memo_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_pos){ ssize_t retval = -ENOMEM; printk("write functionn"); if((data = kmalloc(strlen(buf),GFP_KERNEL)) == N
我正在尝试为char *分配一些内存,如下所示.
static ssize_t memo_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_pos){
    ssize_t retval = -ENOMEM;
    printk("write functionn");

    if((data = kmalloc(strlen(buf),GFP_KERNEL)) == NULL)
        printk("kmalloc failn");

    if(copy_from_user(data,buf,strlen(buf))){
        retval = -EFAULT;
        goto out;
    }
    *f_pos += strlen(buf);
    retval = strlen(buf);

    out:
        return retval;
}

‘data’在头文件中声明为

char *data;

当我调用write函数时,未达到’kmalloc fail’行,这使我相信kmalloc成功,但是当我尝试再次从’data’变量读取时,数据不会显示.

更令人困惑的是,如果我完全摆脱kmalloc位,可以从驱动程序中读取数据.虽然问题在于它之后是其他数据的加载,因为我没有机会memset()它.

我正确使用kmalloc吗?大概不是.我该怎么做?

另外,我的阅读功能如下.

static ssize_t memo_read(struct file *f,char __user *buf,loff_t *f_pos){
    ssize_t retval = 0;

    printk("read functionn");
    printk("data = %sn",data);

    if(*f_pos >= strlen(data)){
        printk("EOFn");
        goto out;
    }

    if(copy_to_user(buf,data,strlen(data))){
        retval = -EFAULT;
        goto out;
    }
    printk("copy_to_user successn");
    *f_pos += strlen(data);
    retval = strlen(data);
    out:
        return retval;
}

谢谢.

解决方法

您应该在用户空间指针上使用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,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,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,count))
    {
        kfree(data);
        retval = -EFAULT;
        goto out;
    }

    *f_pos = count;
    retval = count;
    data_len = count;

out:
    mutex_unlock(&data_mutex);
    return retval;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读