Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp2861612pxv; Mon, 12 Jul 2021 03:50:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwHBp7CocBumSjqwBT9QG1SYzyiFp6Rme+q8WB461e8We8NavWPKTq27xG1HFNepkFvIcLj X-Received: by 2002:a6b:b2d1:: with SMTP id b200mr23656752iof.187.1626087044080; Mon, 12 Jul 2021 03:50:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626087044; cv=none; d=google.com; s=arc-20160816; b=E5EA2p8uv4aKztgmUOE3HFgkdiaWe2XM1hkGt+KZKCDGCutxySleadH6OLvBar0VP7 lVGgTKTq/PRyf08vF6P3iznsMHuAplz6qLT8YVF4UmTS05eJg98mC4Z1uvQ8xBJ83gis MWkUyZfyInSgseUKHMblHv43ltySG/vus/M0zOjVJDAdT4XGK1eqNSi0U2VZvK1p8bzb iXhjpL7sSvRZf2sPgQtkIOcjCH2nFhyENjlmlivENiZvZnpJ3IJxXNsc5q6t+HTbt58L 1pWzEZjIi7zc0O7TOQ4PUmDIdf8Ye4XW+RObK49O9/8grbdZVdAqelKJtHe332yldDNn TqRg== 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=d9xkCwcTGQAL+7bFFzGDZDLvjZW+aqfjbHQO0LQrcDwWttc4bhrbC9uPC1Zqh3RlSY LagwgPy6CxvVa+ygxUhOF1B+5VW4aNrpiqiwnRiaMckOnjV9CJJRkeRhAQpzy9fRgsum c1OWvHOzIodUzh3+aqhJN1Ew2lgO/h7Xh6f8fmLtACm1FVazNXwAxWIfQpvc+8Lg92yh e+hod6MPcYWxrpNIVnicVDawkuvRURIiFayIvNADe1xcD8yWSFJFZVcBY7VuW2wvBzm2 Gp378cs/eSB/t5stcIDaxFei4sFDc3pBCxYTuaJcTQ7HDakauqkSIR7Igg51un+zfF24 /tXA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=dTa7IW9U; 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 n19si16831610jaj.117.2021.07.12.03.50.32; Mon, 12 Jul 2021 03:50:44 -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=dTa7IW9U; 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 S1354207AbhGLIPR (ORCPT + 99 others); Mon, 12 Jul 2021 04:15:17 -0400 Received: from mail.kernel.org ([198.145.29.99]:44106 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344533AbhGLH3f (ORCPT ); Mon, 12 Jul 2021 03:29:35 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2B8236141F; Mon, 12 Jul 2021 07:25:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626074737; bh=7fbMYirB/mGtYtE6wJI6Dx6xC3KIBZASpqlwif7Pb+0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dTa7IW9U8ns2x5TsqZ2dhkBUkyLCc6+fIvYTUwkvNllBTL5sJQXUB7qD9Rhy4Myrl FxtxH2XyHyF5LgcfBEFvtasPUp2/Vrs3rhyCO47csCp0ZV3LRfpdLB97MaJap+CKlt pTU2lFs/mualS2QbFY9+tknsInESJeEt+WtCWdcA= 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.12 681/700] exfat: handle wrong stream entry size in exfat_readdir() Date: Mon, 12 Jul 2021 08:12:44 +0200 Message-Id: <20210712061048.343155408@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210712060924.797321836@linuxfoundation.org> References: <20210712060924.797321836@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);