Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp2738505pxv; Mon, 12 Jul 2021 00:20:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz+Eh+MMELBPtKj8WimCyNzH9MqdL+5CsEl0yAVvvQuP6wfnnlEQW23ey7Q0ckNMbYtMzGd X-Received: by 2002:a02:6946:: with SMTP id e67mr16335976jac.4.1626074415898; Mon, 12 Jul 2021 00:20:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626074415; cv=none; d=google.com; s=arc-20160816; b=zts3/c9cCM0J0TOxOgP0HNRBUVJ21fajNzwJFrdHdRM1KAU4n+fHRZ89JMOswS0h5K SjfTvVWSGpELqWCqyx++oXkC07IV0mp84vtKBX2pInn2VmkMj5DOXkwvmX3SDCDJ0JHo HsrSwYldoQLtGntUKIoHd16PItLzJ9bw516QVKwiweEl5/OCAhT3IBy48Fg1uBDSs9to UzGttwxf6i3AtX/DsaOloGxYxFAoaBM0jiUuVqcZI/93DXIJJWN1OIkjIe+PYRMBff0j g+ftrETs8bB0Pb3ZoLZeF1OAD+EgFKcDuo9WDP6UpcEBI/BtRWBvtg/2WXuEt+n+ylNs YWoA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=kx0yK9UZJ4LBMGFctYy3bIUbH0YhdI5JO0imZCZBXrg=; b=RosaLMlSo2pUVmXMMJ/HlJW6q3qTjkNwXMrdLraAZgC0rrkI21Eov7FKL+yxeVdswa 3ikehWNovVFKv/1tqTxHwRrQVkqsh0q2q98RQcDmjKpiLVNQ8EG+ntNH2ouCDvVt1B4+ 4osFkeyiBedez5eV3cKQ4aLnuhicVSlGxWNv1Ni3LKfGQfb2Gj6gKMM8ll+zVfDu/O8p lnKXvmnpz1jyftW2hi0YNCD7Yw7QgqCJk5Vff0ShpSRMp1Zkb27NBmUz1pkLCOigwaBN 6l1qd8hUP7fw4iSys92OllIsrY+1SE2hC4tgQLzQhsz3lnXVgMN1xsLhMW7eR6EXDQ6D xL8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=htrK3vAb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w21si11843797jah.86.2021.07.12.00.20.04; Mon, 12 Jul 2021 00:20:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=htrK3vAb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343622AbhGLHT5 (ORCPT + 99 others); Mon, 12 Jul 2021 03:19:57 -0400 Received: from mail.kernel.org ([198.145.29.99]:52484 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240953AbhGLGyW (ORCPT ); Mon, 12 Jul 2021 02:54:22 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7F3DC61186; Mon, 12 Jul 2021 06:51:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626072682; bh=7fbMYirB/mGtYtE6wJI6Dx6xC3KIBZASpqlwif7Pb+0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=htrK3vAbFvyvjV//xads+ySeQIryW5QMGYwEuFvxgC0OC4U5YCvYsRpTM78hcruyf bnVS5/nB2XiGE/9nY7t5GS8iYQnALfD7rlv82ekLyGkQDXpaCEw6PXs0/6xiTDB1gQ YR+TwJ9X0R2hoS9tF3MHSoB1gJQeKb7cTSNLR6+8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Florian Cramer , Sungjong Seo , Chris Down , Namjae Jeon Subject: [PATCH 5.10 580/593] exfat: handle wrong stream entry size in exfat_readdir() Date: Mon, 12 Jul 2021 08:12:20 +0200 Message-Id: <20210712060958.979038217@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210712060843.180606720@linuxfoundation.org> References: <20210712060843.180606720@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Namjae Jeon commit 1e5654de0f51890f88abd409ebf4867782431e81 upstream. The compatibility issue between linux exfat and exfat of some camera company was reported from Florian. In their exfat, if the number of files exceeds any limit, the DataLength in stream entry of the directory is no longer updated. So some files created from camera does not show in linux exfat. because linux exfat doesn't allow that cpos becomes larger than DataLength of stream entry. This patch check DataLength in stream entry only if the type is ALLOC_NO_FAT_CHAIN and add the check ensure that dentry offset does not exceed max dentries size(256 MB) to avoid the circular FAT chain issue. Fixes: ca06197382bd ("exfat: add directory operations") Cc: stable@vger.kernel.org # v5.9 Reported-by: Florian Cramer Reviewed-by: Sungjong Seo Tested-by: Chris Down Signed-off-by: Namjae Jeon Signed-off-by: Greg Kroah-Hartman --- fs/exfat/dir.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -62,7 +62,7 @@ static void exfat_get_uniname_from_ext_e static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry) { int i, dentries_per_clu, dentries_per_clu_bits = 0, num_ext; - unsigned int type, clu_offset; + unsigned int type, clu_offset, max_dentries; sector_t sector; struct exfat_chain dir, clu; struct exfat_uni_name uni_name; @@ -85,6 +85,8 @@ static int exfat_readdir(struct inode *i dentries_per_clu = sbi->dentries_per_clu; dentries_per_clu_bits = ilog2(dentries_per_clu); + max_dentries = (unsigned int)min_t(u64, MAX_EXFAT_DENTRIES, + (u64)sbi->num_clusters << dentries_per_clu_bits); clu_offset = dentry >> dentries_per_clu_bits; exfat_chain_dup(&clu, &dir); @@ -108,7 +110,7 @@ static int exfat_readdir(struct inode *i } } - while (clu.dir != EXFAT_EOF_CLUSTER) { + while (clu.dir != EXFAT_EOF_CLUSTER && dentry < max_dentries) { i = dentry & (dentries_per_clu - 1); for ( ; i < dentries_per_clu; i++, dentry++) { @@ -244,7 +246,7 @@ static int exfat_iterate(struct file *fi if (err) goto unlock; get_new: - if (cpos >= i_size_read(inode)) + if (ei->flags == ALLOC_NO_FAT_CHAIN && cpos >= i_size_read(inode)) goto end_of_dir; err = exfat_readdir(inode, &cpos, &de);