Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp1026400yba; Thu, 4 Apr 2019 02:43:53 -0700 (PDT) X-Google-Smtp-Source: APXvYqxOU00uFjJZcBrm6TLjJeScKzJkqeIw0p54+3M8tOdn3LDS+gTVDEajQQGvWJUSF9Vt08FS X-Received: by 2002:aa7:87c5:: with SMTP id i5mr5001847pfo.20.1554371032982; Thu, 04 Apr 2019 02:43:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554371032; cv=none; d=google.com; s=arc-20160816; b=hU6J9z26Kj7+yh5o3BqePaKfCElAuQSPaOWH5Qhrftv/sCMmfSccfDRZn6Sco5hEuy mKnmTP/HOlUl8L2fsqAC6A8Xpe7nc55RWDZhsn5hCE+aw1OVo0V8xnP3UyHIigYM08mk r4QE0YKMp9ZT21EyMgo//+uBxYAy0YUsBoKBXgmXo5HwmNtK+d+4d2+IFzDNSVGF+zsL oC10ZB4Un4HuAZJc2KH3T/tkgWi1rnreYJvP59nCH9YpBqow/rG4n065OwBAVr1V3LvK XVJIy6nA1oAaZyVH+vGxJyUkhyfICO4ImqNY7VOWkwo0gsZorpA5vjh3JruEPeIG1HzE 2N5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Dwzd5Mpv+DFUIe6FDLQ/pUcsaHL9xkxWCkLTHj+Yk7U=; b=RyVEv8ybmfEeXlkrsVtfu5+tAQ5DWlJT9jPDur9Cal4zgJaGfkcbQPyZc4cVG4NQGH kSoNnQFzWEhABlOIkuZTFuhq9YobaH0GwzWtBS1hUj8G6lkahkw4xqrC7xulO7mxk53Y GLCzGlhds3rN8axwBlQQtPQBPEAZERvdKbM60qPVYCvM0umMT4B8h1ZY35iJrtEj5GeP G7YkpKsTQiET3n92Nr2cPr77ZpFfgXwUjTLv7XYc1VBZ8Swr9gSkyoFfNcqUTOTCU+2x bvTQ4Yqix+3XOrltSbIYNTM+P/lTY3kNc1DINsxAuFVQLJu0H4930sFYkMg2oen5iuBF YHTQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=jAglMzlR; 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 b23si15715118pgn.422.2019.04.04.02.43.37; Thu, 04 Apr 2019 02:43:52 -0700 (PDT) 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; dkim=pass header.i=@kernel.org header.s=default header.b=jAglMzlR; 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 S1731329AbfDDJAz (ORCPT + 99 others); Thu, 4 Apr 2019 05:00:55 -0400 Received: from mail.kernel.org ([198.145.29.99]:37788 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730796AbfDDJAx (ORCPT ); Thu, 4 Apr 2019 05:00:53 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6035121741; Thu, 4 Apr 2019 09:00:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1554368452; bh=D1PGjOf+i9TWhdrmvMFVwl4I9WyIC+/SpoGlRTUZRMQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jAglMzlRWxCmd/9OchUvSyUlCuIcz5mQPeoHAc4ca3Z931ybPbmsGenmaEbzzo5tL pgSCCHVni2nXiza83352qEcOOjwcCdmsG+zgWVIR8SnhQbmffWs7iXJ+bDbmVYOjU5 RZLdM36wTd3ygeUUyce/BkZDpul8555E2cHCZDDk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ming Lei , Carlos Maiolino , Jens Axboe , Sasha Levin Subject: [PATCH 4.19 045/187] fs: fix guard_bio_eod to check for real EOD errors Date: Thu, 4 Apr 2019 10:46:22 +0200 Message-Id: <20190404084605.201569065@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190404084603.119654039@linuxfoundation.org> References: <20190404084603.119654039@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.19-stable review patch. If anyone has any objections, please let me know. ------------------ [ Upstream commit dce30ca9e3b676fb288c33c1f4725a0621361185 ] guard_bio_eod() can truncate a segment in bio to allow it to do IO on odd last sectors of a device. It already checks if the IO starts past EOD, but it does not consider the possibility of an IO request starting within device boundaries can contain more than one segment past EOD. In such cases, truncated_bytes can be bigger than PAGE_SIZE, and will underflow bvec->bv_len. Fix this by checking if truncated_bytes is lower than PAGE_SIZE. This situation has been found on filesystems such as isofs and vfat, which doesn't check the device size before mount, if the device is smaller than the filesystem itself, a readahead on such filesystem, which spans EOD, can trigger this situation, leading a call to zero_user() with a wrong size possibly corrupting memory. I didn't see any crash, or didn't let the system run long enough to check if memory corruption will be hit somewhere, but adding instrumentation to guard_bio_end() to check truncated_bytes size, was enough to see the error. The following script can trigger the error. MNT=/mnt IMG=./DISK.img DEV=/dev/loop0 mkfs.vfat $IMG mount $IMG $MNT cp -R /etc $MNT &> /dev/null umount $MNT losetup -D losetup --find --show --sizelimit 16247280 $IMG mount $DEV $MNT find $MNT -type f -exec cat {} + >/dev/null Kudos to Eric Sandeen for coming up with the reproducer above Reviewed-by: Ming Lei Signed-off-by: Carlos Maiolino Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- fs/buffer.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/buffer.c b/fs/buffer.c index c083c4b3c1e7..a550e0d8e965 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -3027,6 +3027,13 @@ void guard_bio_eod(int op, struct bio *bio) /* Uhhuh. We've got a bio that straddles the device size! */ truncated_bytes = bio->bi_iter.bi_size - (maxsector << 9); + /* + * The bio contains more than one segment which spans EOD, just return + * and let IO layer turn it into an EIO + */ + if (truncated_bytes > bvec->bv_len) + return; + /* Truncate the bio.. */ bio->bi_iter.bi_size -= truncated_bytes; bvec->bv_len -= truncated_bytes; -- 2.19.1