2163398192
The decoder library uses variable length arrays on stack. To get rid of them it would be simple to allocate fixed length arrays on stack, but those might become rather large. The other solution is to allocate the buffers in the rs control structure, but this cannot be done as long as the structure can be shared by several users. Sharing is desired because the RS polynom tables are large and initialization is time consuming. To solve this split the codec information out of the control structure and have a pointer to a shared codec in it. Instantiate the control structure for each user, create a new codec if no shareable is avaiable yet. Adjust all affected usage sites to the new scheme. This allows to add per instance decoder buffers to the control structure later on. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Boris Brezillon <boris.brezillon@bootlin.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Kees Cook <keescook@chromium.org> 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>
47 lines
1.2 KiB
C
47 lines
1.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Generic Reed Solomon encoder / decoder library
|
|
*
|
|
* Copyright 2002, Phil Karn, KA9Q
|
|
* May be used under the terms of the GNU General Public License (GPL)
|
|
*
|
|
* Adaption to the kernel by Thomas Gleixner (tglx@linutronix.de)
|
|
*
|
|
* Generic data width independent code which is included by the wrappers.
|
|
*/
|
|
{
|
|
struct rs_codec *rs = rsc->codec;
|
|
int i, j, pad;
|
|
int nn = rs->nn;
|
|
int nroots = rs->nroots;
|
|
uint16_t *alpha_to = rs->alpha_to;
|
|
uint16_t *index_of = rs->index_of;
|
|
uint16_t *genpoly = rs->genpoly;
|
|
uint16_t fb;
|
|
uint16_t msk = (uint16_t) rs->nn;
|
|
|
|
/* Check length parameter for validity */
|
|
pad = nn - nroots - len;
|
|
if (pad < 0 || pad >= nn)
|
|
return -ERANGE;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
fb = index_of[((((uint16_t) data[i])^invmsk) & msk) ^ par[0]];
|
|
/* feedback term is non-zero */
|
|
if (fb != nn) {
|
|
for (j = 1; j < nroots; j++) {
|
|
par[j] ^= alpha_to[rs_modnn(rs, fb +
|
|
genpoly[nroots - j])];
|
|
}
|
|
}
|
|
/* Shift */
|
|
memmove(&par[0], &par[1], sizeof(uint16_t) * (nroots - 1));
|
|
if (fb != nn) {
|
|
par[nroots - 1] = alpha_to[rs_modnn(rs,
|
|
fb + genpoly[0])];
|
|
} else {
|
|
par[nroots - 1] = 0;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|