From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out30-99.freemail.mail.aliyun.com (out30-99.freemail.mail.aliyun.com [115.124.30.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 28A4E299929 for ; Tue, 21 Jul 2026 03:44:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.99 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784605452; cv=none; b=Q6pTEDDdNKtfQ5d2jll/5Gsi4PcRwn484m+pPNkLdvvrHvnUrmZTws3eKGtRcDMJBh/a2+8P5Ac5sXhe1eRql0mUTW7xDQaOCUuo3PexdN9+j1ZsT46wV7NJ8LG98/9bX2MI4DSZ4MdBj7QVAmD23fDlIl9p+CDon7kaiidPmjo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784605452; c=relaxed/simple; bh=hnegSSlkckby6m5sknd1MGq2INDKSBIdHMHXf2jJGb0=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=S/ppFB9MkCxPLAqIDqjnOTFzuzTcyn587pRxzCHasIqMsgVuKSTifU7PJ5kBHE1BdmiODBssKHQd4fdKRoQC46BiTyFwfxmWiutyrRCD1YOgyh+WRuU1zoVQnZFxRxZ/r+RCv2bUgPq7ZcTdMOY5emSrE5PdN8nKAMUh67B8NK0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=jhEMpeGv; arc=none smtp.client-ip=115.124.30.99 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="jhEMpeGv" DKIM-Signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1784605446; h=Message-ID:Date:MIME-Version:Subject:From:To:Content-Type; bh=T55NA4EysOXjtaF5QyCcmdll5bxsIXre+LCQ2EP81Dk=; b=jhEMpeGvs0WhNFDkTofkR4aLeLu8lH7BJ4EtJHZmPzcP3+FE7HED3Hmu7LOJIfUYEPvnSSvFtXvIgrJP4aN8XneDr7Khj++4Utc26EH/cmyQnSBUeB/5uIjwrlwISqAVKd19HHenG163FMPcfaxELRhhBFt0aYE7doXur66thoA= X-Alimail-AntiSpam:AC=PASS;BC=-1|-1;BR=01201311R201e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=maildocker-contentspam033045098064;MF=hsiangkao@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0X7YM.8K_1784605445; Received: from 30.221.132.10(mailfrom:hsiangkao@linux.alibaba.com fp:SMTPD_---0X7YM.8K_1784605445 cluster:ay36) by smtp.aliyun-inc.com; Tue, 21 Jul 2026 11:44:06 +0800 Message-ID: <6179ba55-d53d-4c46-8220-d7340f18e8b5@linux.alibaba.com> Date: Tue, 21 Jul 2026 11:44:04 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v3] erofs: cap LZMA stream pool size From: Gao Xiang To: Michael Bommarito Cc: Yue Hu , Jeffle Xu , Sandeep Dhavale , Chunhai Guo , linux-erofs@lists.ozlabs.org, linux-kernel@vger.kernel.org, Gao Xiang , Chao Yu References: <20260714114729.3760594-1-michael.bommarito@gmail.com> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi Machael, On 2026/7/17 11:43, Gao Xiang wrote: > > > On 2026/7/14 19:47, Michael Bommarito wrote: >> fs/erofs/decompressor_lzma.c sizes the module-global MicroLZMA stream >> pool from num_possible_cpus() when the lzma_streams module parameter is >> unset, then z_erofs_load_lzma_config() preallocates one image-supplied >> dictionary per stream, accepting dictionaries up to 8 MiB.  On high-CPU >> systems, a small EROFS image can pin hundreds of MiB of vmalloc-backed >> decoder state until the erofs module is unloaded. >> >> Impact: an attacker-supplied EROFS image mounted by the system can pin up >> to 8 MiB times the LZMA stream count of kernel vmalloc memory. >> >> Bound the default stream count by a new >> CONFIG_EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS option, default 16, so the >> worst-case default preallocation is 128 MiB while preserving the existing >> per-image dictionary limit.  An explicit lzma_streams module parameter is >> still honoured as-is, so administrators who deliberately size the pool are >> not affected. >> >> Fixes: 622ceaddb764 ("erofs: lzma compression support") >> Cc: stable@vger.kernel.org >> Assisted-by: Claude:claude-opus-4-8 >> Signed-off-by: Michael Bommarito > I submitted the following version to -next: From 4ec57610a769cd93027d12134c75160390b23b08 Mon Sep 17 00:00:00 2001 From: Michael Bommarito Date: Tue, 14 Jul 2026 07:47:29 -0400 Subject: erofs: cap LZMA stream pool size fs/erofs/decompressor_lzma.c sizes the module-global MicroLZMA stream pool from num_possible_cpus() when the lzma_streams module parameter is unset, then z_erofs_load_lzma_config() preallocates one image-supplied dictionary per stream, accepting dictionaries up to 8 MiB. On high-CPU systems, a small EROFS image can pin hundreds of MiB of vmalloc-backed decoder state until the erofs module is unloaded. Impact: An EROFS image mounted by the system can pin up to 8 MiB of vmalloc memory per LZMA stream, either as intended or unexpectedly. Bound the default stream count by a new CONFIG_EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS option, default 16, so the worst-case default preallocation is 128 MiB if the number of CPUs is no less than 16 while preserving the existing per-image dictionary limit. An explicit lzma_streams module parameter is still honoured as-is, so administrators who deliberately size the pool are not affected. Fixes: 622ceaddb764 ("erofs: lzma compression support") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Michael Bommarito Reviewed-by: Gao Xiang Signed-off-by: Gao Xiang --- fs/erofs/Kconfig | 14 ++++++++++++++ fs/erofs/decompressor_lzma.c | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/fs/erofs/Kconfig b/fs/erofs/Kconfig index 4789b1077d8ce..36f027c1c5ac5 100644 --- a/fs/erofs/Kconfig +++ b/fs/erofs/Kconfig @@ -131,6 +131,20 @@ config EROFS_FS_ZIP_LZMA Say N if you want to disable LZMA compression support. +config EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS + int "EROFS LZMA default maximum decompression streams" + depends on EROFS_FS_ZIP_LZMA + range 1 NR_CPUS + default 16 + help + By default EROFS allocates one LZMA decompression stream per CPU. + Each stream can hold a dictionary of up to 8 MiB taken from the + mounted image, so on systems with many CPUs this can reserve a lot + of memory. This caps the default; the lzma_streams module parameter + still overrides it. + + If unsure, keep the default of 16. + config EROFS_FS_ZIP_DEFLATE bool "EROFS DEFLATE compressed data support" depends on EROFS_FS_ZIP diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c index f6692d0f2f04d..6b0cdb446c6ad 100644 --- a/fs/erofs/decompressor_lzma.c +++ b/fs/erofs/decompressor_lzma.c @@ -51,7 +51,8 @@ static int __init z_erofs_lzma_init(void) /* by default, use # of possible CPUs instead */ if (!z_erofs_lzma_nstrms) - z_erofs_lzma_nstrms = num_possible_cpus(); + z_erofs_lzma_nstrms = min_t(unsigned int, num_possible_cpus(), + CONFIG_EROFS_FS_ZIP_LZMA_DEFAULT_MAX_STREAMS); for (i = 0; i < z_erofs_lzma_nstrms; ++i) { struct z_erofs_lzma *strm = kzalloc_obj(*strm); --