lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 14 Nov 2016 00:14:20 +0000
From:   Ben Hutchings <ben@...adent.org.uk>
To:     linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC:     akpm@...ux-foundation.org,
        "kbuild test robot" <fengguang.wu@...el.com>,
        "Mauro Carvalho Chehab" <m.chehab@...sung.com>
Subject: [PATCH 3.16 053/346] [media] ngene: properly handle __user ptr

3.16.39-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Mauro Carvalho Chehab <m.chehab@...sung.com>

commit 04da2daee383391954b34e7d0fe0281d75447d61 upstream.

Sparse is complaining about ngene's bad usage of a __user ptr:

>> drivers/media/pci/ngene/ngene-dvb.c:62:48: sparse: incorrect type in argument 2 (different address spaces)
   drivers/media/pci/ngene/ngene-dvb.c:62:48:    expected unsigned char const [usertype] *buf
   drivers/media/pci/ngene/ngene-dvb.c:62:48:    got char const [noderef] <asn:1>*buf

As this is intercepting a .write() file ops, we can't just memcpy. We need to use
copy_from_user.

Reported-by: kbuild test robot <fengguang.wu@...el.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@...sung.com>
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
 drivers/media/dvb-core/dvb_ringbuffer.c | 26 ++++++++++++++++++++++++++
 drivers/media/dvb-core/dvb_ringbuffer.h |  2 ++
 drivers/media/pci/ngene/ngene-dvb.c     |  2 +-
 3 files changed, 29 insertions(+), 1 deletion(-)

--- a/drivers/media/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb-core/dvb_ringbuffer.c
@@ -166,6 +166,31 @@ ssize_t dvb_ringbuffer_write(struct dvb_
 	return len;
 }
 
+ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
+				  const u8 __user *buf, size_t len)
+{
+	int status;
+	size_t todo = len;
+	size_t split;
+
+	split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
+
+	if (split > 0) {
+		status = copy_from_user(rbuf->data+rbuf->pwrite, buf, split);
+		if (status)
+			return len - todo;
+		buf += split;
+		todo -= split;
+		rbuf->pwrite = 0;
+	}
+	status = copy_from_user(rbuf->data+rbuf->pwrite, buf, todo);
+	if (status)
+		return len - todo;
+	rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
+
+	return len;
+}
+
 ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
 {
 	int status;
@@ -297,3 +322,4 @@ EXPORT_SYMBOL(dvb_ringbuffer_flush_spinl
 EXPORT_SYMBOL(dvb_ringbuffer_read_user);
 EXPORT_SYMBOL(dvb_ringbuffer_read);
 EXPORT_SYMBOL(dvb_ringbuffer_write);
+EXPORT_SYMBOL(dvb_ringbuffer_write_user);
--- a/drivers/media/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb-core/dvb_ringbuffer.h
@@ -133,6 +133,8 @@ extern void dvb_ringbuffer_read(struct d
 */
 extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
 				    size_t len);
+extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
+				         const u8 __user *buf, size_t len);
 
 
 /**
--- a/drivers/media/pci/ngene/ngene-dvb.c
+++ b/drivers/media/pci/ngene/ngene-dvb.c
@@ -59,7 +59,7 @@ static ssize_t ts_write(struct file *fil
 				     (&dev->tsout_rbuf) >= count) < 0)
 		return 0;
 
-	dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count);
+	dvb_ringbuffer_write_user(&dev->tsout_rbuf, buf, count);
 
 	return count;
 }

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ