aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2018-04-22 12:23:55 -0400
committerKees Cook <keescook@chromium.org>2018-04-24 22:50:10 -0400
commit45888b40d2a6221d46bb69959e2600ddba71cc1f (patch)
tree58422ab63f1bcc01b810cb2c7d2a8c7be0fd2bb0
parent964dfce9c2b323a9a9d0bd6764e0f530b40104e4 (diff)
rslib: Allocate decoder buffers to avoid VLAs
To get rid of the variable length arrays on stack in the RS decoder it's necessary to allocate the decoder buffers per control structure instance. All usage sites have been checked for potential parallel decoder usage and fixed where necessary. Kees confirmed that the pstore decoding is strictly single threaded so there should be no surprises. Allocate them in the rs control structure sized depending on the number of roots for the chosen codec and adapt the decoder code to make use of them. Document the fact that decode operations based on a particular rs control instance cannot run in parallel and the caller has to ensure that as it's not possible to provide a proper locking construct which fits all use cases. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Kees Cook <keescook@chromium.org> Cc: Boris Brezillon <boris.brezillon@free-electrons.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Segher Boessenkool <segher@kernel.crashing.org> Cc: Kernel Hardening <kernel-hardening@lists.openwall.com> Cc: Richard Weinberger <richard@nod.at> Cc: Mike Snitzer <snitzer@redhat.com> Cc: Anton Vorontsov <anton@enomsg.org> Cc: Colin Cross <ccross@android.com> Cc: Andrew Morton <akpm@linuxfoundation.org> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Alasdair Kergon <agk@redhat.com> Signed-off-by: Kees Cook <keescook@chromium.org>
-rw-r--r--include/linux/rslib.h2
-rw-r--r--lib/reed_solomon/decode_rs.c20
-rw-r--r--lib/reed_solomon/reed_solomon.c31
3 files changed, 45 insertions, 8 deletions
diff --git a/include/linux/rslib.h b/include/linux/rslib.h
index 6703311beea3..5974cedd008c 100644
--- a/include/linux/rslib.h
+++ b/include/linux/rslib.h
@@ -50,9 +50,11 @@ struct rs_codec {
50/** 50/**
51 * struct rs_control - rs control structure per instance 51 * struct rs_control - rs control structure per instance
52 * @codec: The codec used for this instance 52 * @codec: The codec used for this instance
53 * @buffers: Internal scratch buffers used in calls to decode_rs()
53 */ 54 */
54struct rs_control { 55struct rs_control {
55 struct rs_codec *codec; 56 struct rs_codec *codec;
57 uint16_t buffers[0];
56}; 58};
57 59
58/* General purpose RS codec, 8-bit data width, symbol width 1-15 bit */ 60/* General purpose RS codec, 8-bit data width, symbol width 1-15 bit */
diff --git a/lib/reed_solomon/decode_rs.c b/lib/reed_solomon/decode_rs.c
index 794cced31c75..1db74eb098d0 100644
--- a/lib/reed_solomon/decode_rs.c
+++ b/lib/reed_solomon/decode_rs.c
@@ -21,16 +21,22 @@
21 uint16_t *alpha_to = rs->alpha_to; 21 uint16_t *alpha_to = rs->alpha_to;
22 uint16_t *index_of = rs->index_of; 22 uint16_t *index_of = rs->index_of;
23 uint16_t u, q, tmp, num1, num2, den, discr_r, syn_error; 23 uint16_t u, q, tmp, num1, num2, den, discr_r, syn_error;
24 /* Err+Eras Locator poly and syndrome poly The maximum value
25 * of nroots is 8. So the necessary stack size will be about
26 * 220 bytes max.
27 */
28 uint16_t lambda[nroots + 1], syn[nroots];
29 uint16_t b[nroots + 1], t[nroots + 1], omega[nroots + 1];
30 uint16_t root[nroots], reg[nroots + 1], loc[nroots];
31 int count = 0; 24 int count = 0;
32 uint16_t msk = (uint16_t) rs->nn; 25 uint16_t msk = (uint16_t) rs->nn;
33 26
27 /*
28 * The decoder buffers are in the rs control struct. They are
29 * arrays sized [nroots + 1]
30 */
31 uint16_t *lambda = rsc->buffers + RS_DECODE_LAMBDA * (nroots + 1);
32 uint16_t *syn = rsc->buffers + RS_DECODE_SYN * (nroots + 1);
33 uint16_t *b = rsc->buffers + RS_DECODE_B * (nroots + 1);
34 uint16_t *t = rsc->buffers + RS_DECODE_T * (nroots + 1);
35 uint16_t *omega = rsc->buffers + RS_DECODE_OMEGA * (nroots + 1);
36 uint16_t *root = rsc->buffers + RS_DECODE_ROOT * (nroots + 1);
37 uint16_t *reg = rsc->buffers + RS_DECODE_REG * (nroots + 1);
38 uint16_t *loc = rsc->buffers + RS_DECODE_LOC * (nroots + 1);
39
34 /* Check length parameter for validity */ 40 /* Check length parameter for validity */
35 pad = nn - nroots - len; 41 pad = nn - nroots - len;
36 BUG_ON(pad < 0 || pad >= nn); 42 BUG_ON(pad < 0 || pad >= nn);
diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c
index cb21e8b5a4e0..dfcf54242fb9 100644
--- a/lib/reed_solomon/reed_solomon.c
+++ b/lib/reed_solomon/reed_solomon.c
@@ -37,6 +37,18 @@
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/mutex.h> 38#include <linux/mutex.h>
39 39
40enum {
41 RS_DECODE_LAMBDA,
42 RS_DECODE_SYN,
43 RS_DECODE_B,
44 RS_DECODE_T,
45 RS_DECODE_OMEGA,
46 RS_DECODE_ROOT,
47 RS_DECODE_REG,
48 RS_DECODE_LOC,
49 RS_DECODE_NUM_BUFFERS
50};
51
40/* This list holds all currently allocated rs codec structures */ 52/* This list holds all currently allocated rs codec structures */
41static LIST_HEAD(codec_list); 53static LIST_HEAD(codec_list);
42/* Protection for the list */ 54/* Protection for the list */
@@ -204,6 +216,7 @@ static struct rs_control *init_rs_internal(int symsize, int gfpoly,
204{ 216{
205 struct list_head *tmp; 217 struct list_head *tmp;
206 struct rs_control *rs; 218 struct rs_control *rs;
219 unsigned int bsize;
207 220
208 /* Sanity checks */ 221 /* Sanity checks */
209 if (symsize < 1) 222 if (symsize < 1)
@@ -215,7 +228,13 @@ static struct rs_control *init_rs_internal(int symsize, int gfpoly,
215 if (nroots < 0 || nroots >= (1<<symsize)) 228 if (nroots < 0 || nroots >= (1<<symsize))
216 return NULL; 229 return NULL;
217 230
218 rs = kzalloc(sizeof(*rs), GFP_KERNEL); 231 /*
232 * The decoder needs buffers in each control struct instance to
233 * avoid variable size or large fixed size allocations on
234 * stack. Size the buffers to arrays of [nroots + 1].
235 */
236 bsize = sizeof(uint16_t) * RS_DECODE_NUM_BUFFERS * (nroots + 1);
237 rs = kzalloc(sizeof(*rs) + bsize, gfp);
219 if (!rs) 238 if (!rs)
220 return NULL; 239 return NULL;
221 240
@@ -330,6 +349,11 @@ EXPORT_SYMBOL_GPL(encode_rs8);
330 * The syndrome and parity uses a uint16_t data type to enable 349 * The syndrome and parity uses a uint16_t data type to enable
331 * symbol size > 8. The calling code must take care of decoding of the 350 * symbol size > 8. The calling code must take care of decoding of the
332 * syndrome result and the received parity before calling this code. 351 * syndrome result and the received parity before calling this code.
352 *
353 * Note: The rs_control struct @rsc contains buffers which are used for
354 * decoding, so the caller has to ensure that decoder invocations are
355 * serialized.
356 *
333 * Returns the number of corrected bits or -EBADMSG for uncorrectable errors. 357 * Returns the number of corrected bits or -EBADMSG for uncorrectable errors.
334 */ 358 */
335int decode_rs8(struct rs_control *rsc, uint8_t *data, uint16_t *par, int len, 359int decode_rs8(struct rs_control *rsc, uint8_t *data, uint16_t *par, int len,
@@ -374,6 +398,11 @@ EXPORT_SYMBOL_GPL(encode_rs16);
374 * @corr: buffer to store correction bitmask on eras_pos 398 * @corr: buffer to store correction bitmask on eras_pos
375 * 399 *
376 * Each field in the data array contains up to symbol size bits of valid data. 400 * Each field in the data array contains up to symbol size bits of valid data.
401 *
402 * Note: The rc_control struct @rsc contains buffers which are used for
403 * decoding, so the caller has to ensure that decoder invocations are
404 * serialized.
405 *
377 * Returns the number of corrected bits or -EBADMSG for uncorrectable errors. 406 * Returns the number of corrected bits or -EBADMSG for uncorrectable errors.
378 */ 407 */
379int decode_rs16(struct rs_control *rsc, uint16_t *data, uint16_t *par, int len, 408int decode_rs16(struct rs_control *rsc, uint16_t *data, uint16_t *par, int len,