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>] [day] [month] [year] [list]
Message-Id: <20191030092102.871-1-ptikhomirov@virtuozzo.com>
Date:   Wed, 30 Oct 2019 12:21:02 +0300
From:   Pavel Tikhomirov <ptikhomirov@...tuozzo.com>
To:     Alexander Viro <viro@...iv.linux.org.uk>
Cc:     linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org,
        Pavel Tikhomirov <ptikhomirov@...tuozzo.com>
Subject: [PATCH] fs/ppoll: skip excess EINTR if we never sleep

If while calling sys_ppoll with zero timeout we had received a signal,
we do return -EINTR.

FMPOV the -EINTR should specify that we were interrupted by the signal,
and not that we have a pending signal which does not interfere with us
at all as we were planning to return anyway. We can just return 0 in
these case.

I understand that it is a rare situation that signal comes to us while
in poll with zero timeout, but that reproduced somehow on VZ7 kernel on
CRIU tests.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@...tuozzo.com>
---
 fs/select.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/select.c b/fs/select.c
index 53a0c149f528..54d523e3de7f 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -873,7 +873,7 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
 {
 	poll_table* pt = &wait->pt;
 	ktime_t expire, *to = NULL;
-	int timed_out = 0, count = 0;
+	int timed_out = 0, no_timeout = 0, count = 0;
 	u64 slack = 0;
 	__poll_t busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0;
 	unsigned long busy_start = 0;
@@ -881,10 +881,10 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
 	/* Optimise the no-wait case */
 	if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
 		pt->_qproc = NULL;
-		timed_out = 1;
+		no_timeout = 1;
 	}
 
-	if (end_time && !timed_out)
+	if (end_time && !no_timeout)
 		slack = select_estimate_accuracy(end_time);
 
 	for (;;) {
@@ -921,10 +921,10 @@ static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
 		pt->_qproc = NULL;
 		if (!count) {
 			count = wait->error;
-			if (signal_pending(current))
+			if (!no_timeout && signal_pending(current))
 				count = -ERESTARTNOHAND;
 		}
-		if (count || timed_out)
+		if (count || timed_out || no_timeout)
 			break;
 
 		/* only if found POLL_BUSY_LOOP sockets && not out of time */
-- 
2.21.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ