Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp832845yba; Wed, 24 Apr 2019 10:19:08 -0700 (PDT) X-Google-Smtp-Source: APXvYqx06Phfl5CCSfCqH0c1Im2vyOUQx3Q2lrugD1LxHuiCwzRdQxeCwP2hm0pDGOMw0GLH1Mf+ X-Received: by 2002:a17:902:b602:: with SMTP id b2mr33870895pls.293.1556126348312; Wed, 24 Apr 2019 10:19:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556126348; cv=none; d=google.com; s=arc-20160816; b=BaqnONxHI6YQG3l30AfH4N95F4GqMqiLPSfddyunLEv95eVed55W3fhSb6Fk123yFu G7HF4tuhEwYXUYHaqk8I7kZFh6d3s/HlUnEHd/tsA1K+arW4sOqNccqBZ2bZ57VgOOt+ 1jZ0YtBb7ZbC9Iq5WS73MBGKcaR1PJjrXYHxsnzBYzMShY76R1z92Q38HfagJ7u2hdle AWx1P2EhLP11bLVYjP1f2oUhlTJ2jTAmcIGokWUUMMaPECfjzhPOwxKa8l2ii0Vv3fzc e5VeUZQeWiPgaiNbQSaDkPXncPMTCRmAKNHRbKTh0KRGTmAkT8LJI+Z5cGd8mGLONyG2 ePrQ== 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=nVvjca7Bg9s/ZsRbKUlWyCS7Bt27RepxFGmLASF2Dbk=; b=Oaymh7SvQf9P+gSPCK9P/OrjD4Fe8NiBgLToMcO6FMTDZmjLnSCCAFYodrQygm6kYa i8Ly8RlUJiq4rJJgY4I52YQpec9OwmUNbBrNjnlCInahgzFBocLnpLBP8KgwWjUGBWDV x9yBYlkPf3Yrak0y6AYA8dKp5LxpsE7oI4H0a1ylxJUZ/3WD7sDK/Uhn2R8qTRjcC2ak E230rjULC7YbiAn5IUqbyaP5GdGWMcXYAJD4rRa+ksqwWgZ2prYe8M+Af7CsxsbB7Cij KmHmqUsvdoNm7W8dREwlVJSoQ7A1OCYSWsFrZbFflw3SYp4Pnu4cfr6jce8I6f8eZxYg wb3g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=U9FONgzQ; 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 c13si8014431pgm.206.2019.04.24.10.18.52; Wed, 24 Apr 2019 10:19:08 -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=U9FONgzQ; 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 S2388480AbfDXRQm (ORCPT + 99 others); Wed, 24 Apr 2019 13:16:42 -0400 Received: from mail.kernel.org ([198.145.29.99]:41350 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387857AbfDXRQl (ORCPT ); Wed, 24 Apr 2019 13:16:41 -0400 Received: from localhost (62-193-50-229.as16211.net [62.193.50.229]) (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 CFECE21909; Wed, 24 Apr 2019 17:16:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1556126200; bh=vEGwWl8nNlp9LNF7Sh9GcTK0qgonCqsdrzKH3eaSm58=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=U9FONgzQeQQgnSlk5Bx460mYv801dzDYpo73jc8y1TUF9CANP9tec5ymyS4HbCx4f UqYlj+0lqNBOz7MelTVYjfD2rGzYS5KYf5QG9U6ULDzf5qD0LA+7mOj3STVmY07hqJ v4oJmQDMc4XI+tebcRYgwiqqhH8v32SurE7YL47s= 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.4 026/168] fs: fix guard_bio_eod to check for real EOD errors Date: Wed, 24 Apr 2019 19:07:50 +0200 Message-Id: <20190424170925.213505835@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190424170923.452349382@linuxfoundation.org> References: <20190424170923.452349382@linuxfoundation.org> User-Agent: quilt/0.66 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 [ 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 6f7d519a093b..f278e27bd8c0 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2985,6 +2985,13 @@ void guard_bio_eod(int rw, 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