From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A8B5C47404 for ; Wed, 9 Oct 2019 17:29:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 01EE120679 for ; Wed, 9 Oct 2019 17:29:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1570642161; bh=pzYismJLfx4vIF4SyCyhbDR9A3inGA4T9Ll9hlAjaDc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=x7Yp3r7zSu+iBJTI0hymy+jBMvnL85Kk1B3sIAD4wAzCj8GWwobYdblxd5Vg/pCT/ McHegoTmcZ2yxoCAkIQbPgrJSriGeZ2nw3WXDI+HVc4xfLETkaEuErF9tYO8+J55Fk gtCXG21bRheb9126v7DjtSnvhbd/XTQJg5Zlq0TE= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732861AbfJIR3T (ORCPT ); Wed, 9 Oct 2019 13:29:19 -0400 Received: from mail.kernel.org ([198.145.29.99]:48802 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732213AbfJIRYO (ORCPT ); Wed, 9 Oct 2019 13:24:14 -0400 Received: from sasha-vm.mshome.net (unknown [167.220.2.234]) (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 1684A21D56; Wed, 9 Oct 2019 17:24:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1570641854; bh=pzYismJLfx4vIF4SyCyhbDR9A3inGA4T9Ll9hlAjaDc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gobPve6otbB5UBCpr2m+2faLZCL9pNjwcVTYHogXAZtbDeDCYgXroqrhCrUCwgQs5 MXFmjmZmeAD/jGOgN+ipwDIQSNg5ICR1NS9LOnELvrTRniAjlekiSjG0iP155SZXvY zTlCXXbhvDpr2CoU4rahOhYEsHQup5yWcmJ1/MSQ= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Eric Sandeen , Linus Torvalds , Sasha Levin , linux-fsdevel@vger.kernel.org Subject: [PATCH AUTOSEL 4.19 23/26] vfs: Fix EOVERFLOW testing in put_compat_statfs64 Date: Wed, 9 Oct 2019 13:05:55 -0400 Message-Id: <20191009170558.32517-23-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191009170558.32517-1-sashal@kernel.org> References: <20191009170558.32517-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: Eric Sandeen [ Upstream commit cc3a7bfe62b947b423fcb2cfe89fcba92bf48fa3 ] Today, put_compat_statfs64() disallows nearly any field value over 2^32 if f_bsize is only 32 bits, but that makes no sense. compat_statfs64 is there for the explicit purpose of providing 64-bit fields for f_files, f_ffree, etc. And f_bsize is always only 32 bits. As a result, 32-bit userspace gets -EOVERFLOW for i.e. large file counts even with -D_FILE_OFFSET_BITS=64 set. In reality, only f_bsize and f_frsize can legitimately overflow (fields like f_type and f_namelen should never be large), so test only those fields. This bug was discussed at length some time ago, and this is the proposal Al suggested at https://lkml.org/lkml/2018/8/6/640. It seemed to get dropped amid the discussion of other related changes, but this part seems obviously correct on its own, so I've picked it up and sent it, for expediency. Fixes: 64d2ab32efe3 ("vfs: fix put_compat_statfs64() does not handle errors") Signed-off-by: Eric Sandeen Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin --- fs/statfs.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/fs/statfs.c b/fs/statfs.c index f0216629621d6..56f655f757ffb 100644 --- a/fs/statfs.c +++ b/fs/statfs.c @@ -304,19 +304,10 @@ COMPAT_SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct compat_statfs __user *, static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf) { struct compat_statfs64 buf; - if (sizeof(ubuf->f_bsize) == 4) { - if ((kbuf->f_type | kbuf->f_bsize | kbuf->f_namelen | - kbuf->f_frsize | kbuf->f_flags) & 0xffffffff00000000ULL) - return -EOVERFLOW; - /* f_files and f_ffree may be -1; it's okay - * to stuff that into 32 bits */ - if (kbuf->f_files != 0xffffffffffffffffULL - && (kbuf->f_files & 0xffffffff00000000ULL)) - return -EOVERFLOW; - if (kbuf->f_ffree != 0xffffffffffffffffULL - && (kbuf->f_ffree & 0xffffffff00000000ULL)) - return -EOVERFLOW; - } + + if ((kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL) + return -EOVERFLOW; + memset(&buf, 0, sizeof(struct compat_statfs64)); buf.f_type = kbuf->f_type; buf.f_bsize = kbuf->f_bsize; -- 2.20.1