summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2023-01-08 12:05:00 +0000
committerAidan MacDonald <amachronic@protonmail.com>2023-01-15 16:11:28 -0500
commit56442f6b7f180566c0cf5ccd2e98642d6d9a1dd9 (patch)
tree1759a03b69aec51b947cbe5e3c7495be3d7d8e9a
parent67cb2e3cdc9495ab00ad13c2971222c3da7bb78e (diff)
downloadrockbox-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.c19
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;