Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp770387ybc; Sat, 16 Nov 2019 08:23:18 -0800 (PST) X-Google-Smtp-Source: APXvYqyewRgChQciq0MabotpPMb8f7QwDgJGd3NVAUktq61nHDn6NYwbHFUmHKGMgKO2Bg1w7U1u X-Received: by 2002:adf:9185:: with SMTP id 5mr12264354wri.389.1573921398051; Sat, 16 Nov 2019 08:23:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573921398; cv=none; d=google.com; s=arc-20160816; b=V+Vq8Erh/6U42hI7soyGIQtUSxQ5oTRMh+onf1nWHr5bacw9ppGKZUmvXsPjunjUsm YolGIGPKD/3ffmBRMXqN3+LpeJ4Aq87dWYrwQtaAZ0cYlAHqgdzKWrQuuxMFxaXwDhoN Bdx0o4lmRXigPWssowFYt6dr7wI+4WZ4LkeK2vaSLxGh/6dJpcztdlmtK+INWwwhtwUi 2B9J63Z2nWzbhMWbB5pGFAbbYF2LRrdX0XJY4BlrHT3AtxEnpfhgLX5OFO3l0QvuR058 Sk8s08mLSepLuqmw+BTmdwoTdNi/nUs0OhfWjPSq7hmutjuavD3SldUsF63555iLpVk7 sF/w== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Z786fE7hRyWqt+6L7JOVNGUQ8jkTOV49w65WGqvijmQ=; b=AguEKqU+Ikq2cQOtjPdxHJFtb95ASEcnRWq0jki3ObzW+HCDx4DvGJJeWSVsr66qmq p779J1rAYHg6IopoT5oQIZSbEDsPqhmZpf3cODwOk7cvcYCDEfBVBWl4ErBJ/LeR88eb Tjw0v1bNhwfmO6Adrw+XM9zfC7WT5DMwhxjMbLXuJeFlrjcrNfY98OiQOGqWNyiP5Wcm 0l8GIV+h9oy702Msf80aQpINmbJAJpK6zdjXtcNLP0icLI61eIN39CwyRVw3eGHIhqnk htXtBO97DRTPXn68amAD4muJxwGYB074zKDbpXkdPArgxU/o/y3Q1WAo+JjyHuLBUhC6 P+pA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=NjtAR7ke; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o19si9092188edz.393.2019.11.16.08.22.53; Sat, 16 Nov 2019 08:23:18 -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; dkim=pass header.i=@kernel.org header.s=default header.b=NjtAR7ke; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729755AbfKPQUd (ORCPT + 99 others); Sat, 16 Nov 2019 11:20:33 -0500 Received: from mail.kernel.org ([198.145.29.99]:49392 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728022AbfKPPoa (ORCPT ); Sat, 16 Nov 2019 10:44:30 -0500 Received: from sasha-vm.mshome.net (unknown [50.234.116.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 255BA20833; Sat, 16 Nov 2019 15:44:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1573919069; bh=MY8vZzJfXFISQSXwE+EqUf4Dqx3adqhs2Rjdk7fKzSc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NjtAR7kejMkINgjjxZrU5xqhUox7rIGCUTn25PQQYCpQSq60nsLSIDMovxgC2eT6W 8L4YXr4/g2K9Jxd+MucEFpzYqLPAqojGYcHl5waDu2IQh8WhQGga1a0ECeCwFD6Q51 NktbZBi+u6A0MZZ3vVGymNIMtMfSnkgaDT5eTgy8= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: "Darrick J. Wong" , Christoph Hellwig , Dave Chinner , Sasha Levin , linux-fsdevel@vger.kernel.org Subject: [PATCH AUTOSEL 4.19 141/237] vfs: avoid problematic remapping requests into partial EOF block Date: Sat, 16 Nov 2019 10:39:36 -0500 Message-Id: <20191116154113.7417-141-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191116154113.7417-1-sashal@kernel.org> References: <20191116154113.7417-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Darrick J. Wong" [ Upstream commit 07d19dc9fbe9128378b9e226abe886fd8fd473df ] A deduplication data corruption is exposed in XFS and btrfs. It is caused by extending the block match range to include the partial EOF block, but then allowing unknown data beyond EOF to be considered a "match" to data in the destination file because the comparison is only made to the end of the source file. This corrupts the destination file when the source extent is shared with it. The VFS remapping prep functions only support whole block dedupe, but we still need to appear to support whole file dedupe correctly. Hence if the dedupe request includes the last block of the souce file, don't include it in the actual dedupe operation. If the rest of the range dedupes successfully, then reject the entire request. A subsequent patch will enable us to shorten dedupe requests correctly. When reflinking sub-file ranges, a data corruption can occur when the source file range includes a partial EOF block. This shares the unknown data beyond EOF into the second file at a position inside EOF, exposing stale data in the second file. If the reflink request includes the last block of the souce file, only proceed with the reflink operation if it lands at or past the destination file's current EOF. If it lands within the destination file EOF, reject the entire request with -EINVAL and make the caller go the hard way. A subsequent patch will enable us to shorten reflink requests correctly. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner Signed-off-by: Sasha Levin --- fs/read_write.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/fs/read_write.c b/fs/read_write.c index 5fb5ee5b8cd70..2195380620d02 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1715,6 +1715,34 @@ static int clone_verify_area(struct file *file, loff_t pos, u64 len, bool write) return security_file_permission(file, write ? MAY_WRITE : MAY_READ); } +/* + * Ensure that we don't remap a partial EOF block in the middle of something + * else. Assume that the offsets have already been checked for block + * alignment. + * + * For deduplication we always scale down to the previous block because we + * can't meaningfully compare post-EOF contents. + * + * For clone we only link a partial EOF block above the destination file's EOF. + */ +static int generic_remap_check_len(struct inode *inode_in, + struct inode *inode_out, + loff_t pos_out, + u64 *len, + bool is_dedupe) +{ + u64 blkmask = i_blocksize(inode_in) - 1; + + if ((*len & blkmask) == 0) + return 0; + + if (is_dedupe) + *len &= ~blkmask; + else if (pos_out + *len < i_size_read(inode_out)) + return -EINVAL; + + return 0; +} /* * Check that the two inodes are eligible for cloning, the ranges make @@ -1821,6 +1849,11 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, return -EBADE; } + ret = generic_remap_check_len(inode_in, inode_out, pos_out, len, + is_dedupe); + if (ret) + return ret; + return 1; } EXPORT_SYMBOL(vfs_clone_file_prep_inodes); -- 2.20.1