1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Aidan MacDonald 2023-01-08 12:05:00 +00:00
parent 67cb2e3cdc
commit 56442f6b7f

View file

@ -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;