Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp4072220imu; Sat, 24 Nov 2018 17:52:42 -0800 (PST) X-Google-Smtp-Source: AFSGD/VtoIDe1usl856HM3Lm9Wsvh3kym9JWitgPSrfjcGcAygxx+AyWXeeC8sJaUOcBEzimHNs6 X-Received: by 2002:a17:902:24d:: with SMTP id 71mr21293071plc.225.1543110762897; Sat, 24 Nov 2018 17:52:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543110762; cv=none; d=google.com; s=arc-20160816; b=KRU5XHPN3+7P8E105w7D5/d0sX6jO8Ue0lkU7MQdAkLNOlKdHUwo0+BLHyFQl6QIDd ayY7KYK0S5s+lk1DmBcKAZt5VAZ3Mv8gOkvqnalTdN7k3aSyewNZhloF4oqpoKINIexs TL38EaZ73CKQwTB6kIQapeG6YjU37ZljnzWKkssmp7xpmuCCchEzGjAtFa71BpFF9q1i zHKwLgXYqmxLf7M4bIwmzRXCv7UOa9FkvEEj2NNvi+5+STiO2446IPkUqmqhu6vtvbc3 V/sq8BsitYzDEmj+5xNWY3R3e1atKdHYX1DhC6eQvrcmSVTfA1wwR48nMT7/ZloUTjBK nmbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=TFERdow4lQJsqqjJbGpRo70yrs2IkrTa3O08MYS9S44=; b=Tq+4NF57XHb/pfClfofTxL+c7qpnZVkgGF60yS2FcC9a+mZyo+23toCamoh+ZyXwSc +eF6VOT4pySf5o7WSELXxGZ6c/pDt+wNcid3mYEPuIQubTwn5Jixs4k9u3z/OfldWZH0 rV9+yAkkPWe2bUVR2rt5rKQptPEj5qvIDI5EmPozhdhth6rh1akEtYGkK/7GDHuvlSSY K9NrJaSQYLppk+719b0zhkQbDiBZtdqQpPBB0m3ZKmT/OtysVi6q1y3AL2P40xkA3c8u sCNXiXeKVjg07biuWc8s54tJ2kHcG8MUS3CIrNKW7eu/aV2w+K0azZeUKvWUSvnwkz8W okcg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k12si43749550pgg.382.2018.11.24.17.52.27; Sat, 24 Nov 2018 17:52:42 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727104AbeKYMln (ORCPT + 99 others); Sun, 25 Nov 2018 07:41:43 -0500 Received: from zeniv.linux.org.uk ([195.92.253.2]:56160 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726722AbeKYMln (ORCPT ); Sun, 25 Nov 2018 07:41:43 -0500 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.91 #2 (Red Hat Linux)) id 1gQjZk-0006AT-CR; Sun, 25 Nov 2018 01:51:11 +0000 Date: Sun, 25 Nov 2018 01:51:08 +0000 From: Al Viro To: Slavomir Kaslev Cc: syzbot , davem@davemloft.net, gregkh@linuxfoundation.org, kgraul@linux.ibm.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, stranche@codeaurora.org, syzkaller-bugs@googlegroups.com Subject: Re: WARNING in csum_and_copy_to_iter Message-ID: <20181125015104.GE2217@ZenIV.linux.org.uk> References: <0000000000001ecaa1057b6e4489@google.com> <20181124200357.GC2217@ZenIV.linux.org.uk> <20181124211918.GA20435@box> <20181124214436.GD2217@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20181124214436.GD2217@ZenIV.linux.org.uk> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Nov 24, 2018 at 09:44:36PM +0000, Al Viro wrote: > No point, IMO - the fix isn't hard and bisect hazard created by the whole thing > is both mild (spurious WARN() in case that used to fail anyway) _and_ won't > disappear from reverting, obviously. I'll post a fix later tonight... FWIW, I think the following ought to work; it's obviously a pair of commits (introduction of convenience helper/switch to its use + csum_and_copy_to_iter() for ITER_PIPE), as well as commit message, etc., but I would really appreciate if folks gave it a look _and_ a beating. Signed-off-by: Al Viro --- diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 7ebccb5c1637..621984743268 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -560,6 +560,44 @@ static size_t copy_pipe_to_iter(const void *addr, size_t bytes, return bytes; } +static __wsum csum_and_memcpy(void *to, const void *from, size_t len, + __wsum sum, size_t off) +{ + __wsum next = csum_partial_copy_nocheck(from, to, len, 0); + return csum_block_add(sum, next, off); +} + +static size_t csum_and_copy_to_pipe_iter(const void *addr, size_t bytes, + __wsum *csum, struct iov_iter *i) +{ + struct pipe_inode_info *pipe = i->pipe; + size_t n, r; + size_t off = 0; + __wsum sum = *csum; + int idx; + + if (!sanity(i)) + return 0; + + bytes = n = push_pipe(i, bytes, &idx, &r); + if (unlikely(!n)) + return 0; + for ( ; n; idx = next_idx(idx, pipe), r = 0) { + size_t chunk = min_t(size_t, n, PAGE_SIZE - r); + char *p = kmap_atomic(pipe->bufs[idx].page); + sum = csum_and_memcpy(p + r, addr, chunk, sum, off); + kunmap_atomic(p); + i->idx = idx; + i->iov_offset = r + chunk; + n -= chunk; + off += chunk; + addr += chunk; + } + i->count -= bytes; + *csum = sum; + return bytes; +} + size_t _copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i) { const char *from = addr; @@ -1368,17 +1406,15 @@ size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, err ? v.iov_len : 0; }), ({ char *p = kmap_atomic(v.bv_page); - next = csum_partial_copy_nocheck(p + v.bv_offset, - (to += v.bv_len) - v.bv_len, - v.bv_len, 0); + sum = csum_and_memcpy((to += v.bv_len) - v.bv_len, + p + v.bv_offset, v.bv_len, + sum, off); kunmap_atomic(p); - sum = csum_block_add(sum, next, off); off += v.bv_len; }),({ - next = csum_partial_copy_nocheck(v.iov_base, - (to += v.iov_len) - v.iov_len, - v.iov_len, 0); - sum = csum_block_add(sum, next, off); + sum = csum_and_memcpy((to += v.iov_len) - v.iov_len, + v.iov_base, v.iov_len, + sum, off); off += v.iov_len; }) ) @@ -1412,17 +1448,15 @@ bool csum_and_copy_from_iter_full(void *addr, size_t bytes, __wsum *csum, 0; }), ({ char *p = kmap_atomic(v.bv_page); - next = csum_partial_copy_nocheck(p + v.bv_offset, - (to += v.bv_len) - v.bv_len, - v.bv_len, 0); + sum = csum_and_memcpy((to += v.bv_len) - v.bv_len, + p + v.bv_offset, v.bv_len, + sum, off); kunmap_atomic(p); - sum = csum_block_add(sum, next, off); off += v.bv_len; }),({ - next = csum_partial_copy_nocheck(v.iov_base, - (to += v.iov_len) - v.iov_len, - v.iov_len, 0); - sum = csum_block_add(sum, next, off); + sum = csum_and_memcpy((to += v.iov_len) - v.iov_len, + v.iov_base, v.iov_len, + sum, off); off += v.iov_len; }) ) @@ -1438,8 +1472,12 @@ size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum, const char *from = addr; __wsum sum, next; size_t off = 0; + + if (unlikely(iov_iter_is_pipe(i))) + return csum_and_copy_to_pipe_iter(addr, bytes, csum, i); + sum = *csum; - if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { + if (unlikely(iov_iter_is_discard(i))) { WARN_ON(1); /* for now */ return 0; } @@ -1455,17 +1493,15 @@ size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum, err ? v.iov_len : 0; }), ({ char *p = kmap_atomic(v.bv_page); - next = csum_partial_copy_nocheck((from += v.bv_len) - v.bv_len, - p + v.bv_offset, - v.bv_len, 0); + sum = csum_and_memcpy(p + v.bv_offset, + (from += v.bv_len) - v.bv_len, + v.bv_len, sum, off); kunmap_atomic(p); - sum = csum_block_add(sum, next, off); off += v.bv_len; }),({ - next = csum_partial_copy_nocheck((from += v.iov_len) - v.iov_len, - v.iov_base, - v.iov_len, 0); - sum = csum_block_add(sum, next, off); + sum = csum_and_memcpy(v.iov_base, + (from += v.iov_len) - v.iov_len, + v.iov_len, sum, off); off += v.iov_len; }) )