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-next>] [day] [month] [year] [list]
Message-Id: <1476274060-1785-1-git-send-email-tomasz.majchrzak@intel.com>
Date:   Wed, 12 Oct 2016 14:07:40 +0200
From:   Tomasz Majchrzak <tomasz.majchrzak@...el.com>
To:     linux-kernel@...r.kernel.org
Cc:     dan.j.williams@...el.com, viro@...iv.linux.org.uk,
        aleksey.obitotskiy@...el.com, pawel.baldysiak@...el.com,
        artur.paszkiewicz@...el.com, maksymilian.kunt@...el.com,
        Tomasz Majchrzak <tomasz.majchrzak@...el.com>
Subject: [PATCH v2][RESEND] seq_file: don't set read position for invalid iterator

If kernfs file is empty on a first read, successive read operations
using the same file descriptor will return no data, even when data is
available. Default kernfs 'seq_next' implementation advances iterator
position even when next object is not there. Kernfs 'seq_start' for
following requests will not return iterator as position is already on
the second object.

This bug doesn't allow to monitor badblocks sysfs files from MD raid.
They are initially empty but if data appears at some stage, userspace is
not able to read it. It doesn't affect any released applications but it
is necessary for upcoming bad block support for external metadata in MD
raid.

Signed-off-by: Tomasz Majchrzak <tomasz.majchrzak@...el.com>
Reviewed-by: Dan Williams <dan.j.williams@...el.com>
---
 fs/seq_file.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 6dc4296..74197f4 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -235,7 +235,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
 	p = m->op->start(m, &pos);
 	while (1) {
 		err = PTR_ERR(p);
-		if (!p || IS_ERR(p))
+		if (IS_ERR_OR_NULL(p))
 			break;
 		err = m->op->show(m, p);
 		if (err < 0)
@@ -244,7 +244,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
 			m->count = 0;
 		if (unlikely(!m->count)) {
 			p = m->op->next(m, p, &pos);
-			m->index = pos;
+			if (!IS_ERR_OR_NULL(p))
+				m->index = pos;
 			continue;
 		}
 		if (m->count < m->size)
-- 
1.8.3.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ