diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2023-01-08 12:05:00 +0000 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2023-01-15 16:11:28 -0500 |
commit | 56442f6b7f180566c0cf5ccd2e98642d6d9a1dd9 (patch) | |
tree | 1759a03b69aec51b947cbe5e3c7495be3d7d8e9a | |
parent | 67cb2e3cdc9495ab00ad13c2971222c3da7bb78e (diff) | |
download | rockbox-56442f6b7f.tar.gz rockbox-56442f6b7f.zip |
rbcodec: Fix FLAC out of bounds read
Commit 6bcd830490 ported an optimization to decode_subframe_fixed()
from FFmpeg (upstream commit 08965b22e2). This contains an out of
bounds read, which doesn't affect the decoder output, but makes ASAN
complain.
FFmpeg fixed the out of bounds read (upstream commit 0ec7b71de8) but
that appears to increase code size a lot.
Inlining the initialization of a, b, c, d into the switch produces
similar code as the non-bounds-checked version with only a handful
of instructions of overhead (checked on MIPS & ARM).
Change-Id: I053fac4efc4676b133eb7545c80e23f37fb00d86
-rw-r--r-- | lib/rbcodec/codecs/libffmpegFLAC/decoder.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/lib/rbcodec/codecs/libffmpegFLAC/decoder.c b/lib/rbcodec/codecs/libffmpegFLAC/decoder.c index 5e6aab36f4..1b091dbf83 100644 --- a/lib/rbcodec/codecs/libffmpegFLAC/decoder.c +++ b/lib/rbcodec/codecs/libffmpegFLAC/decoder.c @@ -182,8 +182,8 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order) return 0; } -static int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_order, int bps) ICODE_ATTR_FLAC; -static int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_order, int bps) +//static int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_order, int bps) ICODE_ATTR_FLAC; +int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_order, int bps) { const int blocksize = s->blocksize; unsigned a, b, c, d; @@ -198,28 +198,33 @@ static int decode_subframe_fixed(FLACContext *s, int32_t* decoded, int pred_orde if (decode_residuals(s, decoded, pred_order) < 0) return -4; - a = decoded[pred_order-1]; - b = a - decoded[pred_order-2]; - c = b - decoded[pred_order-2] + decoded[pred_order-3]; - d = c - decoded[pred_order-2] + 2U*decoded[pred_order-3] - decoded[pred_order-4]; - switch(pred_order) { case 0: break; case 1: + a = decoded[pred_order-1]; for (i = pred_order; i < blocksize; i++) decoded[i] = a += decoded[i]; break; case 2: + a = decoded[pred_order-1]; + b = a - decoded[pred_order-2]; for (i = pred_order; i < blocksize; i++) decoded[i] = a += b += decoded[i]; break; case 3: + a = decoded[pred_order-1]; + b = a - decoded[pred_order-2]; + c = b - decoded[pred_order-2] + decoded[pred_order-3]; for (i = pred_order; i < blocksize; i++) decoded[i] = a += b += c += decoded[i]; break; case 4: + a = decoded[pred_order-1]; + b = a - decoded[pred_order-2]; + c = b - decoded[pred_order-2] + decoded[pred_order-3]; + d = c - decoded[pred_order-2] + 2U*decoded[pred_order-3] - decoded[pred_order-4]; for (i = pred_order; i < blocksize; i++) decoded[i] = a += b += c += d += decoded[i]; break; |