Received: by 2002:a05:6a10:d5a5:0:0:0:0 with SMTP id gn37csp3993817pxb; Mon, 4 Oct 2021 14:42:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw3Lsex7jdPrGcra/vFSClVsFADV6B2DQOVyMTFWTbpCUv0m0oN7FbiBhz+I4MgifGNPO2h X-Received: by 2002:a63:c0a:: with SMTP id b10mr12729304pgl.447.1633383748706; Mon, 04 Oct 2021 14:42:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633383748; cv=none; d=google.com; s=arc-20160816; b=yTp2UtRmyd8/i9o7OBSL5AHyc0C74Uo+8Zwt/RExft+09ePUXx4AMZDaKTRvM/FHoB +AQ8UT+xVftiuaXWwGxAfrw9zSLtREQaQdDkmzn/BHfXM+QXOBgJB4+AfRWsggna5hQh KsdqEHL94HazejPWufx2V/+fWzOO8afyq50KzI7eTr1LAPYu4k/ZdMMh9S8qDYezWSzg rwGzza3o8TAfoO+158QtHHdl4kV2+SCf/FGUljrjI9pZpf4Rm/7yKRblKYXiyyw5rVzN AIwXcAo6sYwAh7uvWwdvggme/JWeosSxbAgbIGWxLDNqNwCGS86rhAQE2Xg8vFFKUkhe +Fqg== 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=arg3U+JwoR2kS/dXwWoVpnPdbLCNm00XRUMz38K9HpM=; b=KA9YfKD2Bnhi5YFeObBBc5dlRWy+mIRVL7TF7FD6SAL8mSm7T7kIgE9cqdDir4jYJi oNyCDViUnnr9a/cq4ir1eFOo90cO2Uk9+Gl6aeTXKGeacN+8rSgtfVX3j5TUtAHra9bA IHRVg+KlPw2yfJGNuyzj2RI+ygR7Qm7Ifi2wj8qLkp1qDPd2vloPLUk54JiMFaNXgToy 3tn92XYofyV9rWvnOlrMAagWhnj8fjF0f1g6DhEPO7hb4rYIGbHxSb5Hv4qEHy4JUawq xO2cRLikzxZOvk0uR3xPHlT4NzGhHehRwwO7mvWPd1V2ihocsI6+KOoEVkdWhJurIoRb Qk4Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=0Q4RraG2; 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 u14si21669596pgk.369.2021.10.04.14.42.15; Mon, 04 Oct 2021 14:42:28 -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=0Q4RraG2; 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 S238692AbhJDNmL (ORCPT + 99 others); Mon, 4 Oct 2021 09:42:11 -0400 Received: from mail.kernel.org ([198.145.29.99]:51998 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238367AbhJDNkV (ORCPT ); Mon, 4 Oct 2021 09:40:21 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 49B1263243; Mon, 4 Oct 2021 13:18:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1633353511; bh=RFVMULWlW6WKVHE/aq1jPRvh16HMIOxjmD6igGeMCZI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=0Q4RraG2CCgD6zkVNQaBiwjO0s2kE7fQEG+R/u6a5dwQcOh/7nMkb3Emu9wCpKskD zL575tvEbJ9HbJoMjH224NVLpi0aO/ZRUyx+4BltW8nwLFEV1akypFQDoBUm6I/o4x 1eOkcbuRmyT960UY3bhbMJTNLVsZmxPCQoQBTbZo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, stable@kernel.org, yangerkun , Jan Kara , Theodore Tso Subject: [PATCH 5.14 157/172] ext4: fix potential infinite loop in ext4_dx_readdir() Date: Mon, 4 Oct 2021 14:53:27 +0200 Message-Id: <20211004125050.039072048@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211004125044.945314266@linuxfoundation.org> References: <20211004125044.945314266@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: yangerkun commit 42cb447410d024e9d54139ae9c21ea132a8c384c upstream. When ext4_htree_fill_tree() fails, ext4_dx_readdir() can run into an infinite loop since if info->last_pos != ctx->pos this will reset the directory scan and reread the failing entry. For example: 1. a dx_dir which has 3 block, block 0 as dx_root block, block 1/2 as leaf block which own the ext4_dir_entry_2 2. block 1 read ok and call_filldir which will fill the dirent and update the ctx->pos 3. block 2 read fail, but we has already fill some dirent, so we will return back to userspace will a positive return val(see ksys_getdents64) 4. the second ext4_dx_readdir will reset the world since info->last_pos != ctx->pos, and will also init the curr_hash which pos to block 1 5. So we will read block1 too, and once block2 still read fail, we can only fill one dirent because the hash of the entry in block1(besides the last one) won't greater than curr_hash 6. this time, we forget update last_pos too since the read for block2 will fail, and since we has got the one entry, ksys_getdents64 can return success 7. Latter we will trapped in a loop with step 4~6 Cc: stable@kernel.org Signed-off-by: yangerkun Reviewed-by: Jan Kara Signed-off-by: Theodore Ts'o Link: https://lore.kernel.org/r/20210914111415.3921954-1-yangerkun@huawei.com Signed-off-by: Greg Kroah-Hartman --- fs/ext4/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -551,7 +551,7 @@ static int ext4_dx_readdir(struct file * struct dir_private_info *info = file->private_data; struct inode *inode = file_inode(file); struct fname *fname; - int ret; + int ret = 0; if (!info) { info = ext4_htree_create_dir_info(file, ctx->pos); @@ -599,7 +599,7 @@ static int ext4_dx_readdir(struct file * info->curr_minor_hash, &info->next_hash); if (ret < 0) - return ret; + goto finished; if (ret == 0) { ctx->pos = ext4_get_htree_eof(file); break; @@ -630,7 +630,7 @@ static int ext4_dx_readdir(struct file * } finished: info->last_pos = ctx->pos; - return 0; + return ret < 0 ? ret : 0; } static int ext4_release_dir(struct inode *inode, struct file *filp)