Reported the cleared bytes in case of a partial clear_user instead of -EFAULT, and remove a pointless conditional, as cleared must be non-zero by the time we hit the signal_pending check.
Reported-by: Rasmus Villemoes <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> --- drivers/char/mem.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 1dc99ab158457a..94c2b556cf9728 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -733,14 +733,20 @@ static ssize_t read_zero(struct file *file, char __user *buf, while (count) { size_t chunk = min_t(size_t, count, PAGE_SIZE); + size_t left; - if (clear_user(buf + cleared, chunk)) - return cleared ? cleared : -EFAULT; + left = clear_user(buf + cleared, chunk); + if (unlikely(left)) { + cleared += (chunk - left); + if (!cleared) + return -EFAULT; + break; + } cleared += chunk; count -= chunk; if (signal_pending(current)) - return cleared ? cleared : -ERESTARTSYS; + break; cond_resched(); } -- 2.28.0

