diff options
author | Kees Cook <keescook@chromium.org> | 2019-03-15 10:14:43 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-03-18 09:43:35 +0100 |
commit | 97885140bf64b43adee76e23179eae9bd1393296 (patch) | |
tree | 4a3d804428f2eb42e294b3d3c1deaf81f52def8f /fs/pstore | |
parent | 478035df0705687cf3cfbb32644f434353189672 (diff) | |
download | barebox-97885140bf64b43adee76e23179eae9bd1393296.tar.gz barebox-97885140bf64b43adee76e23179eae9bd1393296.tar.xz |
pstore/ram: Do not use stack VLA for parity workspace
Instead of using a stack VLA for the parity workspace, preallocate a
memory region. The preallocation is done to keep from needing to perform
allocations during crash dump writing, etc. This also fixes a missed
release of librs on free.
Signed-off-by: Kees Cook <keescook@chromium.org>
[p.zabel@pengutronix.de: ported to Barebox from Linux commit f2531f1976d9]
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'fs/pstore')
-rw-r--r-- | fs/pstore/ram_core.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 9de6dc614d..ed48dcddd5 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -80,24 +80,23 @@ static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, uint8_t *data, size_t len, uint8_t *ecc) { int i; - uint16_t par[prz->ecc_info.ecc_size]; /* Initialize the parity buffer */ - memset(par, 0, sizeof(par)); - encode_rs8(prz->rs_decoder, data, len, par, 0); + memset(prz->ecc_info.par, 0, + prz->ecc_info.ecc_size * sizeof(prz->ecc_info.par[0])); + encode_rs8(prz->rs_decoder, data, len, prz->ecc_info.par, 0); for (i = 0; i < prz->ecc_info.ecc_size; i++) - ecc[i] = par[i]; + ecc[i] = prz->ecc_info.par[i]; } static int persistent_ram_decode_rs8(struct persistent_ram_zone *prz, void *data, size_t len, uint8_t *ecc) { int i; - uint16_t par[prz->ecc_info.ecc_size]; for (i = 0; i < prz->ecc_info.ecc_size; i++) - par[i] = ecc[i]; - return decode_rs8(prz->rs_decoder, data, par, len, + prz->ecc_info.par[i] = ecc[i]; + return decode_rs8(prz->rs_decoder, data, prz->ecc_info.par, len, NULL, 0, NULL, 0, NULL); } @@ -210,6 +209,15 @@ static int persistent_ram_init_ecc(struct persistent_ram_zone *prz, return -EINVAL; } + /* allocate workspace instead of using stack VLA */ + prz->ecc_info.par = kmalloc_array(prz->ecc_info.ecc_size, + sizeof(*prz->ecc_info.par), + GFP_KERNEL); + if (!prz->ecc_info.par) { + pr_err("cannot allocate ECC parity workspace\n"); + return -ENOMEM; + } + prz->corrected_bytes = 0; prz->bad_blocks = 0; @@ -393,6 +401,12 @@ void persistent_ram_free(struct persistent_ram_zone *prz) release_sdram_region(prz->res); prz->res = NULL; } + if (prz->rs_decoder) { + free_rs(prz->rs_decoder); + prz->rs_decoder = NULL; + } + kfree(prz->ecc_info.par); + prz->ecc_info.par = NULL; persistent_ram_free_old(prz); kfree(prz); |