问个copy_from_user的问题
在i2c.dev 中 ioctl 的函数里面有 两次 copy_from_user ,第一次已经从用户空间读取数据了, 但是第二次不是从用户读取数据,为什么还要用copy_from_user?? 请问怎么回事,谢谢!
case I2C_RDWR: if (copy_from_user(&rdwr_arg, //第一次拷贝到rdwr_arg (struct i2c_rdwr_ioctl_data __user *)arg, sizeof(rdwr_arg))) return -EFAULT; /* Put an arbitrary limit on the number of messages that can rdwr_pa = (struct i2c_msg *) if (rdwr_pa == NULL) return -ENOMEM; if (copy_from_user(rdwr_pa, rdwr_arg.msgs, //还从rdwr_arg复制,但是这个是内核的数据 |
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
star316 最近很活跃, 赞一个.
这个问题明显没有仔细思考, 踩一个.
贴一下两个结构的定义:
/* This is the structure as used in the I2C_RDWR ioctl call */
struct i2c_rdwr_ioctl_data {
struct i2c_msg __user *msgs; /* pointers to i2c_msgs */
__u32 nmsgs; /* number of i2c_msgs */
};
struct i2c_msg {
__u16 addr; /* slave address */
__u16 flags;
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
#define I2C_M_RD 0x0001 /* read data, from slave to master */
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
__u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */
};
第一次copy了i2c_rdwr_ioctl_data, 第二次copy了i2c_rdwr_ioctl_data->i2c_msg
唉,没办法啊, 东西总得学, 本来不想用系统的框架写驱动,自己写的还容易点, 但是想了想,自己了解一下它们的框架还是蛮好的,说不定以后就用上啦呢?
i2c_rdwr_ioctl_data->i2c_msg 也是里面的元素, 难道第一次没有拷贝内容过去?? 或者拷过去的只是一个指针
正如你所说, copy i2c_rdwr_ioctl_data时, 里面只是一个指针阿, 并不包括元素本身.
哦,那我第二次拷贝如果是不用 rdwr_arg.msgs 参数, 而用 arg.msgs ,可以么?
当然可以,注意加指针类型转换。
5楼大天使说的是正确的。
用arg->msgs
我也不熟悉. 只好你自己分析一下了.
这一功能函数变换的好多,看的卡壳了,再帮我看看最后面一个吧, 谢谢
for( i=0; i<rdwr_arg.nmsgs; i++ ) {
/* Limit the size of the message to a sane amount */
if (rdwr_pa.len > 8192) {
res = -EINVAL;
break;
}
data_ptrs = (u8 __user *)rdwr_pa.buf;
rdwr_pa.buf = kmalloc(rdwr_pa.len, GFP_KERNEL);
if(rdwr_pa.buf == NULL) {
res = -ENOMEM;
break;
}
if(copy_from_user(rdwr_pa.buf,
data_ptrs,
rdwr_pa.len)) {
++i; /* Needs to be kfreed too */
res = -EFAULT;
break;
}
这里的(copy_from_user(rdwr_pa.buf,data_ptrs,rdwr_pa.len)) 应该是拷贝用户的buf的程序,
但是data_ptrs = (u8 __user *)rdwr_pa.buf , 这里指针指向自己了, 怎么会拷贝用户数据???