diff options
author | Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com> | 2016-11-19 14:21:11 +0100 |
---|---|---|
committer | Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com> | 2016-11-23 00:57:10 +0100 |
commit | 946ecd19ea752399bccc751c9339ff74b815587e (patch) | |
tree | 0e211eb72684ab8356d5491ec49b0c9186e9f49a | |
parent | 4e5049a2303ae7fe74216a83206239e4de42c965 (diff) | |
download | ffmpeg-946ecd19ea752399bccc751c9339ff74b815587e.tar.gz |
smacker: limit recursion depth of smacker_decode_bigtree
This fixes segmentation faults due to stack-overflow caused by too deep
recursion.
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
-rw-r--r-- | libavcodec/smacker.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index b8a0c558a6..2d20be9c10 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -129,8 +129,12 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref /** * Decode header tree */ -static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) +static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx, int length) { + if(length > 500) { // Larger length can cause segmentation faults due to too deep recursion. + av_log(NULL, AV_LOG_ERROR, "length too long\n"); + return AVERROR_INVALIDDATA; + } if (hc->current + 1 >= hc->length) { av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); return AVERROR_INVALIDDATA; @@ -159,12 +163,12 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx int r = 0, r_new, t; t = hc->current++; - r = smacker_decode_bigtree(gb, hc, ctx); + r = smacker_decode_bigtree(gb, hc, ctx, length + 1); if(r < 0) return r; hc->values[t] = SMK_NODE | r; r++; - r_new = smacker_decode_bigtree(gb, hc, ctx); + r_new = smacker_decode_bigtree(gb, hc, ctx, length + 1); if (r_new < 0) return r_new; return r + r_new; @@ -275,7 +279,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int goto error; } - if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) + if (smacker_decode_bigtree(gb, &huff, &ctx, 0) < 0) err = -1; skip_bits1(gb); if(ctx.last[0] == -1) ctx.last[0] = huff.current++; |