From 56442f6b7f180566c0cf5ccd2e98642d6d9a1dd9 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Sun, 8 Jan 2023 12:05:00 +0000 Subject: 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 --- lib/rbcodec/codecs/libffmpegFLAC/decoder.c | 19 ++++++++++++------- 1 file 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; -- cgit