From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754336AbbLKJZs (ORCPT ); Fri, 11 Dec 2015 04:25:48 -0500 Received: from wimdewith.com ([188.226.197.86]:46407 "EHLO wimdewith.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751395AbbLKJZq (ORCPT ); Fri, 11 Dec 2015 04:25:46 -0500 From: Wim de With To: gregkh@linuxfoundation.org Cc: devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org, Wim de With Subject: [PATCH v3] staging: gdm72xx: add userspace data struct Date: Fri, 11 Dec 2015 10:25:13 +0100 Message-Id: <1449825913-4604-1-git-send-email-nauxuron@wimdewith.com> X-Mailer: git-send-email 2.6.3 In-Reply-To: <20151211001720.2332a513@lxorguk.ukuu.org.uk> References: <20151211001720.2332a513@lxorguk.ukuu.org.uk> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This fixes the sparse warnings about dereferencing a userspace pointer. Once I updated the sparse annotations, I noticed a bug in gdm_wimax_ioctl() where we pass a user space pointer to gdm_update_fsm() which dereferences it. I fixed this. Signed-off-by: Wim de With --- drivers/staging/gdm72xx/gdm_wimax.c | 12 ++++++++---- drivers/staging/gdm72xx/wm_ioctl.h | 7 ++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index d9ddced..5da9ad9 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; + struct fsm_s fsm_buf; if (cmd != SIOCWMIOCTL) return -EOPNOTSUPP; @@ -482,8 +483,11 @@ 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); + if (copy_from_user(&fsm_buf, req->data.buf, + sizeof(struct fsm_s))) + return -EFAULT; + + gdm_update_fsm(dev, &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