The Reed-Solomon library enforces the constraint `n <= 2^m - 1` via a
BUG_ON() [1], where `n` is `block_size + ecc_size` and `m` is `symsize`
for the pstore RAM backend. A driver providing invalid parameters can
trigger this, leading to a kernel panic. For more details on the theory
behind, see [2].

This issue was discovered during developing chromeos_pstore driver.
Link: 
https://lore.kernel.org/lkml/[email protected]/

Add a check to validate this constraint before initializing Reed-Solomon
codec. On failure, return -EINVAL to prevent the panic.

[1] 
https://elixir.bootlin.com/linux/v6.15/source/lib/reed_solomon/decode_rs.c#L43
[2] https://www.cs.cmu.edu/~guyb/realworld/reedsolomon/reed_solomon_codes.html

Signed-off-by: Naoya Tezuka <[email protected]>
---
 fs/pstore/ram_core.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index f1848cdd6d34..c7a2ff9c5a6c 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -212,6 +212,14 @@ static int persistent_ram_init_ecc(struct 
persistent_ram_zone *prz,
                return -EINVAL;
        }
 
+       if (prz->ecc_info.block_size + prz->ecc_info.ecc_size >
+           (1 << prz->ecc_info.symsize) - 1) {
+               pr_err("%s: invalid ecc parameters (block_size = %d, ecc_size = 
%d, symsize = %d\n",
+                      __func__, prz->ecc_info.block_size,
+                      prz->ecc_info.ecc_size, prz->ecc_info.symsize);
+               return -EINVAL;
+       }
+
        prz->buffer_size -= ecc_total;
        prz->par_buffer = buffer->data + prz->buffer_size;
        prz->par_header = prz->par_buffer +
-- 
2.50.0.rc2.701.gf1e915cc24-goog


Reply via email to