This fixes the sparse warnings about dereferencing a userspace pointer. However, gdm_wimax_ioctl_get_data and gdm_wimax_ioctl_set_data both carefully check whether the pointers and data are valid, gdm_update_fsm does not. It simply casts userspace data to struct fsm_s. I haven't fixed this, and am not sure what to do about it. Signed-off-by: Wim de With <nauxuron@xxxxxxxxxxxxx> --- drivers/staging/gdm72xx/gdm_wimax.c | 17 +++++++++++++---- drivers/staging/gdm72xx/wm_ioctl.h | 7 ++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index d9ddced..16eac61 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -368,7 +368,7 @@ static void kdelete(void **buf) } } -static int gdm_wimax_ioctl_get_data(struct data_s *dst, struct data_s *src) +static int gdm_wimax_ioctl_get_data(struct udata_s *dst, struct data_s *src) { int size; @@ -384,7 +384,7 @@ static int gdm_wimax_ioctl_get_data(struct data_s *dst, struct data_s *src) return 0; } -static int gdm_wimax_ioctl_set_data(struct data_s *dst, struct data_s *src) +static int gdm_wimax_ioctl_set_data(struct data_s *dst, struct udata_s *src) { if (!src->size) { dst->size = 0; @@ -460,6 +460,7 @@ static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct wm_req_s *req = (struct wm_req_s *)ifr; struct nic *nic = netdev_priv(dev); int ret; + void *fsm_buf; if (cmd != SIOCWMIOCTL) return -EOPNOTSUPP; @@ -482,8 +483,16 @@ static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /* NOTE: gdm_update_fsm should be called * before gdm_wimax_ioctl_set_data is called. */ - gdm_update_fsm(dev, - req->data.buf); + fsm_buf = kmalloc(sizeof(fsm_s), GFP_KERNEL); + if (!fsm_buf) + return -ENOMEM; + if (copy_from_user(fsm_buf, req->data.buf, + sizeof(fsm_s))) { + kfree(fsm_buf); + return -EFAULT; + } + gdm_update_fsm(dev, fsm_buf); + kfree(fsm_buf); } ret = gdm_wimax_ioctl_set_data( &nic->sdk_data[req->data_id], &req->data); diff --git a/drivers/staging/gdm72xx/wm_ioctl.h b/drivers/staging/gdm72xx/wm_ioctl.h index ed8f649..631cb1d 100644 --- a/drivers/staging/gdm72xx/wm_ioctl.h +++ b/drivers/staging/gdm72xx/wm_ioctl.h @@ -78,13 +78,18 @@ struct data_s { void *buf; }; +struct udata_s { + int size; + void __user *buf; +}; + struct wm_req_s { union { char ifrn_name[IFNAMSIZ]; } ifr_ifrn; unsigned short cmd; unsigned short data_id; - struct data_s data; + struct udata_s data; /* NOTE: sizeof(struct wm_req_s) must be less than sizeof(struct ifreq). */ }; -- 2.6.3 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel