[PATCH v5 0/4] zram: fix zstd error paths and add parameter validation

Haoqin Huang posted 4 patches 1 month, 4 weeks ago
There is a newer version of this series
drivers/block/zram/backend_842.c     |  8 ++++++++
drivers/block/zram/backend_deflate.c | 11 +++++++++++
drivers/block/zram/backend_lz4.c     |  4 ++++
drivers/block/zram/backend_lz4hc.c   |  4 ++++
drivers/block/zram/backend_lzo.c     |  8 ++++++++
drivers/block/zram/backend_lzorle.c  |  8 ++++++++
drivers/block/zram/backend_zstd.c    |  7 +++++--
drivers/block/zram/zram_drv.c        | 29 ++++++++++++++++------------
8 files changed, 65 insertions(+), 14 deletions(-)
[PATCH v5 0/4] zram: fix zstd error paths and add parameter validation
Posted by Haoqin Huang 1 month, 4 weeks ago
From: Haoqin Huang <haoqinhuang@tencent.com>

Patch 1 removes zstd_release_params() from both zstd_create() and
zstd_setup_params() error paths, the former is a layering violation
in a per-CPU callback, the latter is redundant as zcomp_init() already
calls release_params() on setup failure.

Patch 2 rejects zero-size dictionaries and prints an error on dict
load failure (currently errors are silently swallowed).

Patch 3 validates dict and level parameters in each backend's
.setup_params(), rejecting unsupported combinations and out-of-range
levels.

Patch 4 resets per-priority params on algorithm change before init.

Changes since v4:
  - Patch 1: merged zstd_setup_params() zstd_release_params() removal;
    reworded commit message
  - Patch 2: removed "zram:" prefix from pr_err (pr_fmt already adds
    it); reworded commit message
  - Patch 3: dropped lz4 U16_MAX upper bound (the library has no
    limit); changed lz4hc lower bound from LZ4HC_MIN_CLEVEL to < 1
    (the library supports levels 1-2); rebased on tree with deflate
    winbits validation
  - Patch 4: moved comp_params_reset() up instead of using a forward
    declaration

v4: https://lore.kernel.org/all/20260730060133.80233-1-haoqinhuang7@gmail.com/

Haoqin Huang (4):
  zram: do not release zstd global params from error paths
  zram: reject zero-size dictionary
  zram: validate parameters in each backend's setup_params
  zram: reset per-priority params when changing algorithm before init

 drivers/block/zram/backend_842.c     |  8 ++++++++
 drivers/block/zram/backend_deflate.c | 11 +++++++++++
 drivers/block/zram/backend_lz4.c     |  4 ++++
 drivers/block/zram/backend_lz4hc.c   |  4 ++++
 drivers/block/zram/backend_lzo.c     |  8 ++++++++
 drivers/block/zram/backend_lzorle.c  |  8 ++++++++
 drivers/block/zram/backend_zstd.c    |  7 +++++--
 drivers/block/zram/zram_drv.c        | 29 ++++++++++++++++------------
 8 files changed, 65 insertions(+), 14 deletions(-)

-- 
2.43.7
[PATCH v6 0/5] zram: fix zstd error paths and add parameter validation
Posted by Haoqin Huang 1 month, 4 weeks ago
From: Haoqin Huang <haoqinhuang@tencent.com>

Patch 1 removes zstd_release_params() from both zstd_create() and
zstd_setup_params() error paths -- the former is a layering violation
in a per-CPU callback, the latter is redundant as zcomp_init() already
calls release_params() on setup failure.

Patch 2 rejects zero-size dictionaries and prints distinct error
messages for sz < 0 (returns the original error code) and sz == 0
("empty file"). Currently errors are silently swallowed.

Patch 3 adds pr_fmt to each backend file so that pr_err() messages
are auto-prefixed with the algorithm name.

Patch 4 validates dict and level parameters in each backend's
.setup_params(), rejecting unsupported combinations and out-of-range
levels.

Patch 5 resets per-priority params on algorithm change before init.

Changes since v5:
  - Patch 2: split pr_err into sz < 0 and sz == 0 branches
  - New patch 3: add pr_fmt to all backends; tweak winbits message;
    add missing SPDX headers to lz4 and lz4hc
  - Patch 4: removed inline algo-name prefixes (now handled by pr_fmt);
    added comment for lz4hc < 1 lower bound; added braces to if
    branches for consistency

v5: https://lore.kernel.org/all/20260803141256.60599-1-haoqinhuang7@gmail.com/

Haoqin Huang (5):
  zram: do not release zstd global params from error paths
  zram: reject zero-size dictionary
  zram: add pr_fmt to backend files
  zram: validate parameters in each backend's setup_params
  zram: reset per-priority params when changing algorithm before init

 drivers/block/zram/backend_842.c     | 10 +++++++++
 drivers/block/zram/backend_deflate.c | 17 ++++++++++++--
 drivers/block/zram/backend_lz4.c     | 10 ++++++++-
 drivers/block/zram/backend_lz4hc.c   | 16 +++++++++++++-
 drivers/block/zram/backend_lzo.c     | 10 +++++++++
 drivers/block/zram/backend_lzorle.c  | 10 +++++++++
 drivers/block/zram/backend_zstd.c    | 11 +++++++---
 drivers/block/zram/zram_drv.c        | 33 ++++++++++++++++++----------
 8 files changed, 98 insertions(+), 19 deletions(-)

-- 
2.43.7
Re: [PATCH v6 0/5] zram: fix zstd error paths and add parameter validation
Posted by Sergey Senozhatsky 1 month, 4 weeks ago
On (26/08/04 17:38), Haoqin Huang wrote:
> From: Haoqin Huang <haoqinhuang@tencent.com>
> 
> Patch 1 removes zstd_release_params() from both zstd_create() and
> zstd_setup_params() error paths -- the former is a layering violation
> in a per-CPU callback, the latter is redundant as zcomp_init() already
> calls release_params() on setup failure.
> 
> Patch 2 rejects zero-size dictionaries and prints distinct error
> messages for sz < 0 (returns the original error code) and sz == 0
> ("empty file"). Currently errors are silently swallowed.
> 
> Patch 3 adds pr_fmt to each backend file so that pr_err() messages
> are auto-prefixed with the algorithm name.
> 
> Patch 4 validates dict and level parameters in each backend's
> .setup_params(), rejecting unsupported combinations and out-of-range
> levels.
> 
> Patch 5 resets per-priority params on algorithm change before init.
> 
> Changes since v5:
>   - Patch 2: split pr_err into sz < 0 and sz == 0 branches
>   - New patch 3: add pr_fmt to all backends; tweak winbits message;
>     add missing SPDX headers to lz4 and lz4hc
>   - Patch 4: removed inline algo-name prefixes (now handled by pr_fmt);
>     added comment for lz4hc < 1 lower bound; added braces to if
>     branches for consistency

Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Re: [PATCH v6 0/5] zram: fix zstd error paths and add parameter validation
Posted by Sergey Senozhatsky 1 month, 4 weeks ago
On (26/08/04 18:53), Sergey Senozhatsky wrote:
> > Patch 1 removes zstd_release_params() from both zstd_create() and
> > zstd_setup_params() error paths -- the former is a layering violation
> > in a per-CPU callback, the latter is redundant as zcomp_init() already
> > calls release_params() on setup failure.
> > 
> > Patch 2 rejects zero-size dictionaries and prints distinct error
> > messages for sz < 0 (returns the original error code) and sz == 0
> > ("empty file"). Currently errors are silently swallowed.
> > 
> > Patch 3 adds pr_fmt to each backend file so that pr_err() messages
> > are auto-prefixed with the algorithm name.
> > 
> > Patch 4 validates dict and level parameters in each backend's
> > .setup_params(), rejecting unsupported combinations and out-of-range
> > levels.
> > 
> > Patch 5 resets per-priority params on algorithm change before init.
> > 
> > Changes since v5:
> >   - Patch 2: split pr_err into sz < 0 and sz == 0 branches
> >   - New patch 3: add pr_fmt to all backends; tweak winbits message;
> >     add missing SPDX headers to lz4 and lz4hc
> >   - Patch 4: removed inline algo-name prefixes (now handled by pr_fmt);
> >     added comment for lz4hc < 1 lower bound; added braces to if
> >     branches for consistency
> 
> Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>

Oh, and also
Tested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Re: [PATCH v6 0/5] zram: fix zstd error paths and add parameter validation
Posted by Andrew Morton 1 month, 4 weeks ago
On Tue,  4 Aug 2026 17:38:36 +0800 Haoqin Huang <haoqinhuang7@gmail.com> wrote:

> Patch 1 removes zstd_release_params() from both zstd_create() and
> zstd_setup_params() error paths -- the former is a layering violation
> in a per-CPU callback, the latter is redundant as zcomp_init() already
> calls release_params() on setup failure.
> 
> Patch 2 rejects zero-size dictionaries and prints distinct error
> messages for sz < 0 (returns the original error code) and sz == 0
> ("empty file"). Currently errors are silently swallowed.
> 
> Patch 3 adds pr_fmt to each backend file so that pr_err() messages
> are auto-prefixed with the algorithm name.
> 
> Patch 4 validates dict and level parameters in each backend's
> .setup_params(), rejecting unsupported combinations and out-of-range
> levels.
> 
> Patch 5 resets per-priority params on algorithm change before init.
> 

Thanks.  AI review pointed at a few things, most of them pre-existing:
	https://sashiko.dev/#/patchset/20260804093841.67920-1-haoqinhuang7@gmail.com
[PATCH v6 1/5] zram: do not release zstd global params from error paths
Posted by Haoqin Huang 1 month, 4 weeks ago
From: Haoqin Huang <haoqinhuang@tencent.com>

zstd_setup_params() creates global cdict and ddict stored in
params->drv_data, shared across all per-CPU contexts. The per-CPU
zstd_create() error path called zstd_release_params(), which freed
those globally-shared objects. This is a layering violation: a
per-CPU callback should only clean up its own context, not release
resources owned by the compression lifecycle.

zstd_setup_params() called zstd_release_params() on its own error
path as well, but zcomp_init() already calls release_params() when
setup fails, so this is redundant.

Remove zstd_release_params() from both error paths.

Signed-off-by: Haoqin Huang <haoqinhuang@tencent.com>
Signed-off-by: Rongwei Wang <zigiwang@tencent.com>
---
 drivers/block/zram/backend_zstd.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index d00b548056dc..5fabc3e7e975 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -85,7 +85,6 @@ static int zstd_setup_params(struct zcomp_params *params)
 	return 0;
 
 error:
-	zstd_release_params(params);
 	return -EINVAL;
 }
 
@@ -161,7 +160,6 @@ static int zstd_create(struct zcomp_params *params, struct zcomp_ctx *ctx)
 	return 0;
 
 error:
-	zstd_release_params(params);
 	zstd_destroy(ctx);
 	return -EINVAL;
 }
-- 
2.43.7
[PATCH v6 2/5] zram: reject zero-size dictionary
Posted by Haoqin Huang 1 month, 4 weeks ago
From: Haoqin Huang <haoqinhuang@tencent.com>

kernel_read_file_from_path() already rejects empty files (i_size <= 0)
and returns -EINVAL, but the current implementation only checks for
sz < 0 without logging any information. Use sz == 0 to reject the
zero-size case and print distinct error messages for each failure type.

Signed-off-by: Haoqin Huang <haoqinhuang@tencent.com>
Signed-off-by: Rongwei Wang <zigiwang@tencent.com>
---
 drivers/block/zram/zram_drv.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index cfa98846ac48..f73e30b61067 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1700,8 +1700,16 @@ static int comp_params_store(struct zram *zram, u32 prio, s32 level,
 						INT_MAX,
 						NULL,
 						READING_POLICY);
-		if (sz < 0)
+		if (sz < 0) {
+			pr_err("failed to load dictionary %s (err=%zd)\n",
+			       dict_path, sz);
+			return sz;
+		}
+		if (sz == 0) {
+			pr_err("failed to load dictionary %s (empty file)\n",
+			       dict_path);
 			return -EINVAL;
+		}
 	}
 
 	zram->params[prio].dict_sz = sz;
-- 
2.43.7
[PATCH v6 3/5] zram: add pr_fmt to backend files
Posted by Haoqin Huang 1 month, 4 weeks ago
From: Haoqin Huang <haoqinhuang@tencent.com>

Add pr_fmt to each backend so that pr_err() messages are auto-prefixed
with the algorithm name. While at it, tweak the deflate winbits
pr_err to avoid a duplicated "deflate" prefix.

Signed-off-by: Haoqin Huang <haoqinhuang@tencent.com>
Signed-off-by: Rongwei Wang <zigiwang@tencent.com>
---
 drivers/block/zram/backend_842.c     | 2 ++
 drivers/block/zram/backend_deflate.c | 4 +++-
 drivers/block/zram/backend_lz4.c     | 4 ++++
 drivers/block/zram/backend_lz4hc.c   | 4 ++++
 drivers/block/zram/backend_lzo.c     | 2 ++
 drivers/block/zram/backend_lzorle.c  | 2 ++
 drivers/block/zram/backend_zstd.c    | 2 ++
 7 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/block/zram/backend_842.c b/drivers/block/zram/backend_842.c
index 10d9d5c60f53..d9b8a6bba2cb 100644
--- a/drivers/block/zram/backend_842.c
+++ b/drivers/block/zram/backend_842.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+#define pr_fmt(fmt) "842: " fmt
+
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sw842.h>
diff --git a/drivers/block/zram/backend_deflate.c b/drivers/block/zram/backend_deflate.c
index b3f7d08b49d9..ee26e6c9282f 100644
--- a/drivers/block/zram/backend_deflate.c
+++ b/drivers/block/zram/backend_deflate.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+#define pr_fmt(fmt) "deflate: " fmt
+
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
@@ -30,7 +32,7 @@ static int deflate_setup_params(struct zcomp_params *params)
 		s32 wb = params->deflate.winbits;
 
 		if ((wb < -15 || wb > -9) && (wb < 9 || wb > 15)) {
-			pr_err("invalid deflate winbits: %d\n", wb);
+			pr_err("invalid winbits %d\n", wb);
 			return -EINVAL;
 		}
 	}
diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c
index c449d511ba86..6d58956ed5b2 100644
--- a/drivers/block/zram/backend_lz4.c
+++ b/drivers/block/zram/backend_lz4.c
@@ -1,3 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#define pr_fmt(fmt) "lz4: " fmt
+
 #include <linux/kernel.h>
 #include <linux/lz4.h>
 #include <linux/slab.h>
diff --git a/drivers/block/zram/backend_lz4hc.c b/drivers/block/zram/backend_lz4hc.c
index f6a336acfe20..c0c3715087c8 100644
--- a/drivers/block/zram/backend_lz4hc.c
+++ b/drivers/block/zram/backend_lz4hc.c
@@ -1,3 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#define pr_fmt(fmt) "lz4hc: " fmt
+
 #include <linux/kernel.h>
 #include <linux/lz4.h>
 #include <linux/slab.h>
diff --git a/drivers/block/zram/backend_lzo.c b/drivers/block/zram/backend_lzo.c
index 4c906beaae6b..84330dea6af5 100644
--- a/drivers/block/zram/backend_lzo.c
+++ b/drivers/block/zram/backend_lzo.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+#define pr_fmt(fmt) "lzo: " fmt
+
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/lzo.h>
diff --git a/drivers/block/zram/backend_lzorle.c b/drivers/block/zram/backend_lzorle.c
index 10640c96cbfc..b3b03a008b64 100644
--- a/drivers/block/zram/backend_lzorle.c
+++ b/drivers/block/zram/backend_lzorle.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+#define pr_fmt(fmt) "lzo-rle: " fmt
+
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/lzo.h>
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index 5fabc3e7e975..fb61acdaef67 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+#define pr_fmt(fmt) "zstd: " fmt
+
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-- 
2.43.7
[PATCH v6 4/5] zram: validate parameters in each backend's setup_params
Posted by Haoqin Huang 1 month, 4 weeks ago
From: Haoqin Huang <haoqinhuang@tencent.com>

Dict and level parameters are silently accepted even for backends
that do not support them. Validate these parameters in each backend's
.setup_params() to reject unsupported combinations and out-of-range
levels with a specific error message.

Signed-off-by: Haoqin Huang <haoqinhuang@tencent.com>
Signed-off-by: Rongwei Wang <zigiwang@tencent.com>
---
 drivers/block/zram/backend_842.c     |  8 ++++++++
 drivers/block/zram/backend_deflate.c | 13 ++++++++++++-
 drivers/block/zram/backend_lz4.c     |  6 +++++-
 drivers/block/zram/backend_lz4hc.c   | 12 +++++++++++-
 drivers/block/zram/backend_lzo.c     |  8 ++++++++
 drivers/block/zram/backend_lzorle.c  |  8 ++++++++
 drivers/block/zram/backend_zstd.c    |  7 ++++++-
 7 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/drivers/block/zram/backend_842.c b/drivers/block/zram/backend_842.c
index d9b8a6bba2cb..3846a04c69d7 100644
--- a/drivers/block/zram/backend_842.c
+++ b/drivers/block/zram/backend_842.c
@@ -15,6 +15,14 @@ static void release_params_842(struct zcomp_params *params)
 
 static int setup_params_842(struct zcomp_params *params)
 {
+	if (params->dict_sz) {
+		pr_err("dictionary is not supported\n");
+		return -EOPNOTSUPP;
+	}
+	if (params->level != ZCOMP_PARAM_NOT_SET) {
+		pr_err("compression level is not supported\n");
+		return -EOPNOTSUPP;
+	}
 	return 0;
 }
 
diff --git a/drivers/block/zram/backend_deflate.c b/drivers/block/zram/backend_deflate.c
index ee26e6c9282f..f71b11bcac78 100644
--- a/drivers/block/zram/backend_deflate.c
+++ b/drivers/block/zram/backend_deflate.c
@@ -24,8 +24,19 @@ static void deflate_release_params(struct zcomp_params *params)
 
 static int deflate_setup_params(struct zcomp_params *params)
 {
-	if (params->level == ZCOMP_PARAM_NOT_SET)
+	if (params->dict_sz) {
+		pr_err("dictionary is not supported\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (params->level == ZCOMP_PARAM_NOT_SET) {
 		params->level = Z_DEFAULT_COMPRESSION;
+	} else if (params->level < Z_DEFAULT_COMPRESSION ||
+		   params->level > Z_BEST_COMPRESSION) {
+		pr_err("invalid compression level %d\n", params->level);
+		return -EINVAL;
+	}
+
 	if (params->deflate.winbits == ZCOMP_PARAM_NOT_SET) {
 		params->deflate.winbits = DEFLATE_DEF_WINBITS;
 	} else {
diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c
index 6d58956ed5b2..1e28104ad964 100644
--- a/drivers/block/zram/backend_lz4.c
+++ b/drivers/block/zram/backend_lz4.c
@@ -32,8 +32,12 @@ static int lz4_setup_params(struct zcomp_params *params)
 	LZ4_stream_t *dict_stream;
 	int ret;
 
-	if (params->level == ZCOMP_PARAM_NOT_SET)
+	if (params->level == ZCOMP_PARAM_NOT_SET) {
 		params->level = LZ4_ACCELERATION_DEFAULT;
+	} else if (params->level < LZ4_ACCELERATION_DEFAULT) {
+		pr_err("invalid compression level %d\n", params->level);
+		return -EINVAL;
+	}
 
 	if (!params->dict || !params->dict_sz)
 		return 0;
diff --git a/drivers/block/zram/backend_lz4hc.c b/drivers/block/zram/backend_lz4hc.c
index c0c3715087c8..d8aa01bb258f 100644
--- a/drivers/block/zram/backend_lz4hc.c
+++ b/drivers/block/zram/backend_lz4hc.c
@@ -22,8 +22,18 @@ static void lz4hc_release_params(struct zcomp_params *params)
 
 static int lz4hc_setup_params(struct zcomp_params *params)
 {
-	if (params->level == ZCOMP_PARAM_NOT_SET)
+	if (params->level == ZCOMP_PARAM_NOT_SET) {
 		params->level = LZ4HC_DEFAULT_CLEVEL;
+	} else if (params->level < 1 || params->level > LZ4HC_MAX_CLEVEL) {
+		/*
+		 * Use < 1 rather than < LZ4HC_MIN_CLEVEL here because
+		 * LZ4HC_compress_generic() only clamps levels below 1
+		 * (levels 1 and 2 are valid). LZ4HC_MIN_CLEVEL (3) is
+		 * advisory and not enforced by the library.
+		 */
+		pr_err("invalid compression level %d\n", params->level);
+		return -EINVAL;
+	}
 
 	return 0;
 }
diff --git a/drivers/block/zram/backend_lzo.c b/drivers/block/zram/backend_lzo.c
index 84330dea6af5..d83f92cf757c 100644
--- a/drivers/block/zram/backend_lzo.c
+++ b/drivers/block/zram/backend_lzo.c
@@ -14,6 +14,14 @@ static void lzo_release_params(struct zcomp_params *params)
 
 static int lzo_setup_params(struct zcomp_params *params)
 {
+	if (params->dict_sz) {
+		pr_err("dictionary is not supported\n");
+		return -EOPNOTSUPP;
+	}
+	if (params->level != ZCOMP_PARAM_NOT_SET) {
+		pr_err("compression level is not supported\n");
+		return -EOPNOTSUPP;
+	}
 	return 0;
 }
 
diff --git a/drivers/block/zram/backend_lzorle.c b/drivers/block/zram/backend_lzorle.c
index b3b03a008b64..1b120d062c92 100644
--- a/drivers/block/zram/backend_lzorle.c
+++ b/drivers/block/zram/backend_lzorle.c
@@ -14,6 +14,14 @@ static void lzorle_release_params(struct zcomp_params *params)
 
 static int lzorle_setup_params(struct zcomp_params *params)
 {
+	if (params->dict_sz) {
+		pr_err("dictionary is not supported\n");
+		return -EOPNOTSUPP;
+	}
+	if (params->level != ZCOMP_PARAM_NOT_SET) {
+		pr_err("compression level is not supported\n");
+		return -EOPNOTSUPP;
+	}
 	return 0;
 }
 
diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c
index fb61acdaef67..08da3810cffd 100644
--- a/drivers/block/zram/backend_zstd.c
+++ b/drivers/block/zram/backend_zstd.c
@@ -60,8 +60,13 @@ static int zstd_setup_params(struct zcomp_params *params)
 		return -ENOMEM;
 
 	params->drv_data = zp;
-	if (params->level == ZCOMP_PARAM_NOT_SET)
+	if (params->level == ZCOMP_PARAM_NOT_SET) {
 		params->level = zstd_default_clevel();
+	} else if (params->level < zstd_min_clevel() ||
+		   params->level > zstd_max_clevel()) {
+		pr_err("invalid compression level %d\n", params->level);
+		goto error;
+	}
 
 	zp->cprm = zstd_get_params(params->level, PAGE_SIZE);
 
-- 
2.43.7
[PATCH v6 5/5] zram: reset per-priority params when changing algorithm before init
Posted by Haoqin Huang 1 month, 4 weeks ago
From: Haoqin Huang <haoqinhuang@tencent.com>

Parameters validated against one algorithm may be invalid for another
(e.g. lz4 accepts level=65535 but zstd does not).  Although algorithm
changes are blocked after disksize is set, they are allowed before
device initialization.  Reset per-priority params on algorithm change
so that stale parameters do not silently carry over.

Signed-off-by: Haoqin Huang <haoqinhuang@tencent.com>
Signed-off-by: Rongwei Wang <zigiwang@tencent.com>
---
 drivers/block/zram/zram_drv.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index f73e30b61067..56183c827e1b 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -1652,6 +1652,17 @@ static void comp_algorithm_set(struct zram *zram, u32 prio, const char *alg)
 	zram->comp_algs[prio] = alg;
 }
 
+static void comp_params_reset(struct zram *zram, u32 prio)
+{
+	struct zcomp_params *params = &zram->params[prio];
+
+	vfree(params->dict);
+	params->level = ZCOMP_PARAM_NOT_SET;
+	params->deflate.winbits = ZCOMP_PARAM_NOT_SET;
+	params->dict_sz = 0;
+	params->dict = NULL;
+}
+
 static int __comp_algorithm_store(struct zram *zram, u32 prio, const char *buf)
 {
 	const char *alg;
@@ -1672,20 +1683,10 @@ static int __comp_algorithm_store(struct zram *zram, u32 prio, const char *buf)
 	}
 
 	comp_algorithm_set(zram, prio, alg);
+	comp_params_reset(zram, prio);
 	return 0;
 }
 
-static void comp_params_reset(struct zram *zram, u32 prio)
-{
-	struct zcomp_params *params = &zram->params[prio];
-
-	vfree(params->dict);
-	params->level = ZCOMP_PARAM_NOT_SET;
-	params->deflate.winbits = ZCOMP_PARAM_NOT_SET;
-	params->dict_sz = 0;
-	params->dict = NULL;
-}
-
 static int comp_params_store(struct zram *zram, u32 prio, s32 level,
 			     const char *dict_path,
 			     struct deflate_params *deflate_params)
-- 
2.43.7